GNU parallel
è una variante di xargs
. Entrambi hanno interfacce molto simili e se stai cercando aiuto su parallel
, potresti avere più fortuna nella ricerca di informazioni su xargs
.
Detto questo, il modo in cui entrambi funzionano è abbastanza semplice. Con il loro comportamento predefinito, entrambi i programmi leggono l'input da STDIN, quindi suddividono l'input in token basati su spazi bianchi. Ognuno di questi token viene quindi passato come argomento a un programma fornito. L'impostazione predefinita per xargs consiste nel passare più token possibile al programma e quindi avviare un nuovo processo quando viene raggiunto il limite. Non sono sicuro di come funziona l'impostazione predefinita per il parallelo.
Ecco un esempio:
> echo "foo bar \
baz" | xargs echo
foo bar baz
Ci sono alcuni problemi con il comportamento di default, quindi è comune vedere diverse varianti.
Il primo problema è che, poiché gli spazi bianchi vengono utilizzati per la tokenizzazione, qualsiasi file con spazi vuoti in essi causerà la rottura di parallele e xarg. Una soluzione è tokenize attorno al carattere NULL invece. find
fornisce anche un'opzione per rendere questo facile da fare:
> echo "Success!" > bad\ filename
> find . "bad\ filename" -print0 | xargs -0 cat
Success!
L'opzione -print0
dice find
per separare i file con il carattere NULL invece di spazi bianchi.
L'opzione -0
indica a xargs
di utilizzare il carattere NULL per tokenizzare ogni argomento.
Si noti che parallel
è un po 'meglio di xargs
in quanto il suo comportamento predefinito è il tokenize attorno solo a linee nuove, quindi è meno necessario modificare il comportamento predefinito.
Un altro problema comune è che si potrebbe voler controllare come gli argomenti vengono passati a xargs
o parallel
. Se è necessario disporre di una posizione specifica degli argomenti passati al programma, è possibile utilizzare {}
per specificare dove posizionare l'argomento.
> mkdir new_dir
> find -name *.xml | xargs mv {} new_dir
Ciò spostare tutti i file nella directory corrente e sottodirectory nella directory new_dir. In realtà si scompone in quanto segue:
> find -name *.xml | xargs echo mv {} new_dir
> mv foo.xml new_dir
> mv bar.xml new_dir
> mv baz.xml new_dir
in modo da prendere in considerazione come xargs
e parallel
lavoro, si dovrebbe teoricamente essere in grado di vedere il problema con il vostro comando. find . -name '*.xml'
genererà un elenco di file xml da passare al programma script.sh
.
> find . -name '*.xml' | parallel -j2 echo script.sh {}
> script.sh foo.xml
> script.sh bar.xml
> script.sh baz.xml
Tuttavia, ls | parallel -j2 script.sh {}
genererà un elenco di tutti i file nella directory corrente da passare al programma script.sh.
> ls | parallel -j2 echo script.sh {}
> script.sh some_directory
> script.sh some_file
> script.sh foo.xml
> ...
una più corretta variante della versione ls
sarebbe come segue:
> ls *.xml | parallel -j2 script.sh {}
Tuttavia, e importante differenza tra questa e la versione scoperta è che la trovano saranno la ricerca in tutte le sottodirectory per i file, mentre ls cercherà solo la directory corrente. La versione equivalente find
del comando precedente ls
sarebbe la seguente:
> find -maxdepth 1 -name '*.xml'
Questo cercherà solo la directory corrente.
hai provato a provare con #!/ bin/bash -x che ti mostrerà se i tuoi argomenti non sono quelli che pensi dovrebbero essere. –
Sono sempre imbarazzato quando ciò accade, ma quando ho provato a riprodurre questo problema il giorno successivo (e uso il -x come suggerito) non riuscivo a riprodurlo e tutto funzionava alla grande. Sono stato in grado di usare ls o trovare con successo ogni volta. Mi chiedo se in qualche modo ho messo a tacere il mio ambiente e un log out/a chiarito qualcosa. – Dave