Utilizzo di parentesi graffe {} come argomenti per i comandi e le loro opzioni


11

Esempi

Di recente ho trovato esempi di utilizzo di coppie di parentesi graffe {}, senza nulla tra le parentesi graffe di apertura e chiusura, come argomenti per i comandi e persino per le loro opzioni:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

Nessuna documentazione

Il mio problema è che non riesco a trovare una documentazione nel Manuale GNU Bash che descriva l'utilizzo di {}in tale contesto come negli esempi sopra.

Non credo si tratti di un'espansione dei parametri , perché un segno di dollaro deve precedere le parentesi graffe in un'espansione dei parametri come in ${}.

Non può essere nemmeno un'espansione di parentesi graffe , perché assume la forma di {x..y[..incr]}, dove xe ynon sono facoltativi.

Inoltre, non può neppure essere un raggruppamento di comandi , poiché {}viene utilizzato come argomento.

Domande

  1. Cosa {}significa in generale una coppia di parentesi graffe come argomento per qualsiasi comando che la accetta?

  2. Dove posso trovare una documentazione che descrive l'utilizzo di {}come argomenti?


Alcuni comandi hanno queste opzioni {}- il che significa targetsagire su, con findcomando, è rimuovere / rmtrovare file.
Tuyen Pham,

Risposte:


16

Queste parentesi graffe sono lasciate sole da bash; appartengono finde xargs, rispettivamente, e sono descritti nelle loro pagine man.

man find

-exec comando ;

Esegui comando ; vero se viene restituito lo stato 0. Tutti i seguenti argomenti da trovare sono considerati argomenti per il comando fino a quando non ;si incontra un argomento costituito da . La stringa {}viene sostituita dal nome del file corrente che viene elaborato ovunque si presenti negli argomenti del comando, non solo negli argomenti in cui è solo, come in alcune versioni di find. Entrambe queste costruzioni potrebbero aver bisogno di essere salvate (con a \) o quotate per proteggerle dall'espansione della shell. Vedere la sezione ESEMPI per esempi sull'uso -execdell'opzione. Il comando specificato viene eseguito una volta per ogni file corrispondente. Il comando viene eseguito nella directory iniziale. Ci sono inevitabili problemi di sicurezza che circondano l'uso -exec dell'azione; dovresti usare -execdirinvece l' opzione.

-exec comando {} +

Questa variante -execdell'azione esegue il comando specificato sui file selezionati, ma la riga di comando viene creata aggiungendo alla fine ciascun nome di file selezionato; il numero totale di invocazioni del comando sarà molto inferiore al numero di file corrispondenti. La riga di comando è costruita più o meno allo stesso modo che xargscrea le sue righe di comando. È {}consentita solo un'istanza di all'interno del comando. Il comando viene eseguito nella directory iniziale. Se si findverifica un errore, ciò può a volte causare un'uscita immediata, quindi alcuni comandi in sospeso potrebbero non essere eseguiti affatto. Questa variante di -execrestituisce sempre true.

-execdir comando ;

-execdir comando {} +

Come -exec, ma il comando specificato viene eseguito dalla sottodirectory contenente il file corrispondente, che normalmente non è la directory in cui hai iniziato a trovare. Questo è un metodo molto più sicuro per invocare i comandi, in quanto evita le condizioni di gara durante la risoluzione dei percorsi dei file corrispondenti. Come per l' -exec azione, la + forma di -execdir costruirà una riga di comando per elaborare più di un file corrispondente, ma ogni invocazione data del comando elencherà solo i file presenti nella stessa sottodirectory. Se si utilizza questa opzione, è necessario assicurarsi che la $PATHvariabile di ambiente non faccia riferimento.; in caso contrario, un utente malintenzionato può eseguire tutti i comandi che preferisce lasciando un file con un nome appropriato in una directory in cui verrà eseguito -execdir. Lo stesso vale per avere voci in $PATHcui sono vuote o che non sono nomi di directory assoluti. Se si findverifica un errore, ciò può a volte causare un'uscita immediata, quindi alcuni comandi in sospeso potrebbero non essere eseguiti affatto. Il risultato dell'azione dipende dall'utilizzo +della ;variante o ; -execdir il comando {} + restituisce sempre true, mentre il -execdir comando {} ; restituisce true solo se il comando restituisce 0.

man xargs

-I replace-str

Sostituisci le occorrenze di replace-str negli argomenti iniziali con nomi letti dall'input standard. Inoltre, gli spazi vuoti non quotati non terminano gli elementi di input; invece il separatore è il carattere di nuova riga. Implica -xe -L 1.

-i[ sostituisci-str ], --replace[ =sostituisci-str ]

Questa opzione è sinonimo di -Ireplace-str se si specifica replace-str . Se manca l'argomento sostituisci-str , l'effetto è lo stesso di -I{}. Questa opzione è obsoleta; usa -Iinvece.

Modifica: e qui PERCHÉ bash ignora quelle parentesi graffe:

man bash

{ elenco; }

l'elenco viene semplicemente eseguito nell'attuale ambiente shell. l'elenco deve essere terminato con una nuova riga o punto e virgola. Questo è noto come comando di gruppo. Lo stato di ritorno è lo stato di uscita dell'elenco. Notare che, diversamente dai metacaratteri ( e ) , { e } sono parole riservate e devono apparire quando una parola riservata può essere riconosciuta. Dal momento che non causano un'interruzione di parola, devono essere separati dall'elenco da spazi bianchi o da un altro metacarattere della shell.

Per enfasi: l' elenco deve essere terminato con una nuova riga o punto e virgola .


1
Grazie! Sono infastidito dal fatto che chiunque abbia scritto man xargsnon si sia nemmeno preso la briga di spiegare cosa {}significhi effettivamente, né l'autore ha reindirizzato (nessun gioco di parole) il lettore alla spiegazione -execnella pagina man di find.
Niko Gambt,

@NikoGambt - Mi dispiace ...
tink

5
@NikoGambt Bene, {} in realtà non significa nulla per xargs, tranne per essere il valore predefinito per -i, che è deprecato. Non sono sicuro di quale spiegazione sia necessaria oltre a ciò. Nell'esempio che hai pubblicato, potrebbe anche essere stato xargs -Iab echo ab; è una scelta puramente arbitraria.
Casuale 832,

@ Random832 Dopo aver fatto qualche altro test con -I, ora capisco cosa fa effettivamente quell'opzione . Sì, {}è arbitrario, come hai detto. Ero solo confuso dalla spiegazione If the replace-str argument is missing, the effect is the same as -I{}. Se -Isenza argomenti fossero gli stessi -I{}, allora cat foo | xargs -I echo {}produrrebbe lo stesso risultato della corsa cat foo | xargs -I{} echo {}. Tuttavia, non sono gli stessi. Il primo è un errore e ciò che mi ha confuso ancora di più è stato il messaggio di errore xargs: {}: No such file or directory, ma questo è dovuto solo all'implementazione.
Niko Gambt,

1
@NikoGambt -I(I maiuscolo) non può essere eseguito senza un argomento. L'argomento -Iera echo. Questa è la differenza principale tra -Ie -i(e il motivo -i è deprecato, poiché le opzioni con argomenti non richiesti sono rare e confuse)
Casuale832
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.