2011-07-07 10 views
11

Obiettivo: elencare i file in tutti i barattoli.xargs jar tvf - non funziona

Questo funziona:

for f in `find . -name "*.jar"`; do jar tvf $f; done 

Questo funziona troppo:

find . -name "*.jar" -exec jar tvf {} \; 

Questo non (non stampa alcun output):

find . -name "*.jar" | xargs jar tvf 

Perché quest'ultimo non funziona ?

risposta

14

Questo funziona

find . -name "*.jar"|xargs -n 1 jar -tvf 
+0

Sì, grazie. – Synesso

7

Il problema è che jar tvf permette solo un file da passare in.

Il ciclo for esegue i file uno per uno

jar tvf 1.jar; jar tvf 2.jar; ... 

Tuttavia, xargs cerca di adattare quanti più argomenti su una riga possibile. Così sta provando il seguente:

jar tvf 1.jar 2.jar ... 

È possibile verificare questo mettendo un'eco nel comando:

for f in `find . -name "*.jar"`; do echo jar tvf $f; done 
find . -name "*.jar" | xargs echo jar tvf 

La soluzione corretta è la xargs dicono di utilizzare un solo parametro per ogni comando:

find . -name "*.jar" | xargs -n 1 jar tvf 

o

find . -name "*.jar" | xargs -i jar tvf {} # Find style parameter placement 
+0

Grazie per la spiegazione. – Synesso

+0

Grazie per il suggerimento '-i', bello. – sarnold

+0

@sarnold devi sapere che questo argomento ('-i') è deprecato. vedi man xargs ('xargs (GNU findutils) 4.4.2'):' Questa opzione è deprecata; usa -I invece. Non c'è alcun problema a usarlo in modalità interattiva ma lo eviterei negli script poiché potrebbe scomparire in una versione futuristica di xargs. – Lynch

6

Non funziona perché gli xarg invocano solo un processo con tutti gli argomenti.

C'è un modo per richiamare un nuovo processo per ogni argomento utilizzando -I'{}'.

Provate a capire:

$ seq 10 | xargs echo 
1 2 3 4 5 6 7 8 9 10 
$ seq 10 | xargs -I'{}' echo {} 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10