Come utilizzare il comando xargs su Linux

Hai bisogno di mettere insieme alcuni comandi Linux, ma uno di loro non accetta input in pipe? xargs può prendere l’output da un comando e inviarlo a un altro comando come parametri.

Tutte le utility Linux standard hanno tre flussi di dati associati a loro. Sono il flusso di input standard (stdin), il flusso di output standard (stdout) e il flusso di errore standard (stderr).

Questi flussi funzionano con il testo. Inviamo input (stdin) a un comando utilizzando il testo e la risposta (stdout) viene scritta nella finestra del terminale come testo. I messaggi di errore vengono scritti anche nella finestra del terminale come testo (stderr).

Una delle grandi caratteristiche dei sistemi operativi Linux e Unix è la capacità di convogliare l’output stdout da un comando nell’input stdin di un secondo comando. Al primo comando non interessa che il suo output non vada in una finestra di terminale e al secondo comando non interessa che il suo input non provenga da una tastiera.

Sebbene tutti i comandi Linux abbiano i tre flussi standard, non tutti accettano lo stdout di un altro comando come input per il loro stdin. Ciò significa che non puoi inviare loro input.

xargs è un comando per la creazione di pipeline di esecuzione utilizzando i flussi di dati standard. Usando xargs possiamo fare in modo che comandi come echo, rm e mkdir accettino l’input standard come argomenti.

Il comando xargs

xargs accetterà l’input in pipe. Può anche accettare input da un file. xargs usa quell’input come parametri per i comandi con cui gli abbiamo detto di lavorare. Se non diciamo a xargs di lavorare con un comando specifico, userà di default echo.

Possiamo usarlo per dimostrare come xargs genererà sempre una singola riga di output, anche da input su più righe.

Se usiamo l’opzione -1 (elenca un file per riga) con ls, otteniamo un file singola colonna di nomi di file.

ls -1 ./*.sh

Elenca i file di script della shell nella directory corrente.

output di ls in una finestra di terminale

Otteniamo una singola colonna come previsto. Se lo convogliamo attraverso xargs cosa otteniamo?

ls -1 ./*.sh | xargs

ls -1 ./*.sh |  xargs in una finestra di terminale

L’output viene scritto nella finestra del terminale, come un lungo flusso di testo.

Viene trasmesso attraverso xargs in una finestra di terminale

È questa capacità che consente a xargs di inserire parametri in altri comandi.

Usare xargs con wc

Possiamo usare xargs per fare in modo che wc conti facilmente il file parole, caratteri e linee in più file.

ls *.page | xargs wc

ls * .page |  xargs wc in una finestra di terminale

Questo è ciò che succede:

ls elenca i file * .page e passa l’elenco a xargs.
xargs passa i nomi dei file a wc.
wc tratta i nomi dei file come se li avesse ricevuti come parametri della riga di comando.

wc in una finestra di terminale

Le statistiche per ogni file vengono visualizzate insieme al totale complessivo.

Utilizzo di xargs con conferma

Possiamo usare l’opzione -p (interattiva) per fare in modo che xargs ci chieda conferma che siamo felici che proceda.

Se passiamo una stringa di nomi di file a touch, tramite xargs, touch will creare i file per noi.

echo 'one two three' | xargs -p touch

echo 'uno due tre' |  xargs -p tocco in una finestra di terminale

Viene visualizzato il comando che sta per essere eseguito e xargs attende che noi rispondiamo digitando “y” o “Y”, o “n” o “N” e premendo Invio.

Se si preme semplicemente Invio, viene trattato come “n”. Il comando viene eseguito solo se si digita “y” o “Y”.

xargs che richiede conferma in una finestra di terminale

Abbiamo premuto “y” e premuto Invio. Possiamo usare ls per verificare che i file siano stati creati.

ls one two three

output di ls in una finestra di terminale

Utilizzo di xargs con più comandi

Possiamo usare più comandi con xargs usando l’opzione -I (argomenti iniziali).

Questa opzione definisce una “stringa di sostituzione”. Ogni volta che il token per la stringa di sostituzione appare nella riga di comando, vengono inseriti i valori forniti a xargs.

Usiamo il comando tree per guardare le sottodirectory dalla directory corrente. L’opzione -d (directory) fa sì che l’albero ignori i file e crei rapporti solo sulle directory.

tree -d

tree -d in una finestra di terminale

Esiste un’unica sottodirectory chiamata “immagini”.

In un file chiamato “directory.txt”, abbiamo i nomi di alcune directory che vorremmo creare. Possiamo guardarne il contenuto usando cat.

cat directories.txt

cat directory.txt in una finestra di terminale

Lo useremo come dati di input per xargs. Il comando a cui andremo è questo:

cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'

Questo si rompe in questo modo:

cat directories.txt |: questo spinge il contenuto del file directrories.txt (tutti i nuovi nomi di directory) in xargs.
xargs -I%: definisce una “stringa di sostituzione” con il token “%”.
sh -c: questo avvia una nuova subshell. Il -c (comando) dice alla shell di leggere i comandi dalla riga di comando.
‘eco %; mkdir% ‘: ciascuno dei token “%” verrà sostituito dai nomi di directory passati da xargs. Il comando echo stamperà il nome della directory; il comando mkdir creerà la directory.

cat directory.txt |  xargs -I% sh -c 'echo%;  mkdir% 'in una finestra di terminale

Le directory sono elencate una per una.

output di xargs in una finestra di terminale

Possiamo usare ancora una volta tree per verificare che le directory siano state create.

tree -d

output dall'albero in una finestra di terminale

Copia di file in più posizioni

Possiamo usare xargs per permetterci di copiare file in più posizioni con un singolo comando.

Stiamo per reindirizzare i nomi di due directory in xargs come parametri di input. Diremo a xargs di passare solo uno di questi parametri alla volta al comando con cui sta lavorando.

In questo caso, il comando è cp. Quindi l’effetto è di chiamare cp due volte, ogni volta con una delle due directory come parametro della riga di comando. Il parametro xargs che consente che ciò accada è l’opzione -n ​​(numero massimo). Impostiamo questo in modo che sia uno.

Stiamo anche usando l’opzione -v (verbose) con cp in modo che riporti cosa sta succedendo.

echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

echo ~ / Backups / ~ / Documents / page-files / |  xargs -n 1 cp -v ./*.page in una finestra di terminale

I file vengono copiati nelle due directory, una directory alla volta. cp segnala ogni azione di copia di file in modo che possiamo vederla in atto.

output di xargs e cp in una finestra di terminale

Eliminazione di file in directory annidate

Se i nomi dei file contengono spazi e caratteri strani, come i caratteri di nuova riga, xargs non sarà in grado di interpretarli correttamente. Possiamo superare questo problema usando l’opzione -0 (null terminator). Questo dice a xargs di usare il carattere null come delimitatore finale per i nomi dei file.

Useremo find in questo esempio. find ha la sua opzione per trattare con gli spazi bianchi e strani caratteri nei nomi dei file. È l’opzione -print0 (nome completo, carattere nullo).

find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"

Questo si rompe in questo modo:

trova . -name “* .png”: find sta per cercare dalla directory corrente “.” per oggetti con nomi che corrispondono a “* .png” che sono file (tipo -f).
-print0: i nomi verranno terminati da un carattere nullo e verranno presi in considerazione spazi e caratteri strani.
xargs -0: xargs considererà anche i nomi dei file con terminazione null e spazi e caratteri strani non causeranno problemi.
rm -v -rf “{}”: rm sarà dettagliato e riferirà cosa sta succedendo (-v). Sarà ricorsivo (-r) e esaminerà le sottodirectory annidate e rimuoverà i file senza chiedere (-f). Il “{}” è sostituito da ogni nome di file.

trova .  -nome

Viene eseguita la ricerca in tutte le sottodirectory e vengono eliminati i file che corrispondono al modello di ricerca.

Output di rm in una finestra di terminale

Rimozione di directory annidate

Supponiamo di voler rimuovere un insieme di sottodirectory annidate. l’albero ce li farà vedere.

tree -d

tree -d in una finestra di terminale

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

Questo comando utilizzerà find per cercare in modo ricorsivo all’interno della directory corrente. L’obiettivo della ricerca è una directory chiamata “level_one”. I nomi delle directory vengono passati tramite xargs a rm.

trova .  -nome

Le uniche modifiche significative tra questo comando e il comando precedente sono che il termine di ricerca è il nome della directory più in alto e -type d dice a find di cercare directory, non file.

output da find e xargs e rm in una finestra di terminale

Il nome di ogni directory viene stampato non appena viene rimosso. Possiamo controllare con l’albero:

tree -d

tree -d in una finestra di terminale

Tutte le sottodirectory nidificate vengono eliminate.

Eliminazione di tutti i file, tranne un tipo di file

Possiamo usare find, xargs e rm per eliminare tutti i file tranne un tipo che vogliamo conservare. È leggermente controintuitivo, ma forniamo il nome del tipo di file che desideriamo mantenere, non il nome di quelli che vogliamo eliminare.

L’opzione -not dice a find di restituire i nomi dei file che non corrispondono al modello di ricerca. Usiamo ancora una volta l’opzione -I (argomenti iniziali) con xargs. Questa volta il token di sostituzione della stringa che stiamo definendo è “{}”. Questo si comporterà esattamente come il token di sostituzione della stringa che abbiamo generato in precedenza, che era una “%”.

find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

trova .  -tipo f -non - nome

Possiamo controllare con ls. Gli unici file rimasti nella directory sono quelli che corrispondono al modello di ricerca “* .sh”.

ls -l

output da ls in una finestra di terminale

Creazione di un file di archivio con Xargs

Possiamo usare find per cercare file e passarli attraverso xargs a tar, per creare un file di archivio.

Cercheremo nella directory corrente. Il modello di ricerca è “* .page”, quindi cercheremo file “.page”.

find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

trova ./ - nome

I file vengono elencati come previsto, durante la creazione del file di archivio.

output di tar in una finestra di terminale

Il mediatore dei dati

A volte hai bisogno di un po ‘di impalcatura quando impili le cose insieme. xargs colma il divario tra i comandi che possono pompare informazioni e i comandi che non sono costruiti per accoglierli.

Sia xarg che find hanno un numero enorme di opzioni. Sei incoraggiato a controllare le loro pagine man per saperne di più.