bash xargs: Der gleiche Befehl liefert eine andere Ausgabe

591
stas

Wenn ich renne

ls -1 *.a | xargs -I{} echo {} | sed 's/.a//' 

Die Ausgabe ist

1 2 3 

Wenn ich renne

ls -1 *.a | xargs -I{} bash -c "echo {} $(echo {} | sed 's/.a//')" 

und die Ausgabe ist

1.a 1.a 2.a 2.a 3.a 3.a 

Was ist der Grund für diese Anomalie?

1
Ich nehme an, die Shell läuft vor `$ (echo {} | sed's / .a // ')`, das mit `{}` antwortet. Dann haben Sie `bash -c" echo {} {} "`, worauf `xargs -I {}` an der `{}` die Ausgabe von `ls * .a 'einstellt. Ps> Sie brauchen '-1' nicht, wenn Sie 'ls' pfeifen. _Somehow weiß, dass er gepiped wird, und es ist automatisch. Hastur vor 7 Jahren 1
Hastur hat recht. Führen Sie `bash -xc 'ls * .a | aus xargs -I {} bash -c "echo {} $ (echo {} | sed s / .a //)" '`und Sie werden sehen. guest-vm vor 7 Jahren 1
@Guest Thx, ich schrieb das gleiche ... :-) aber mit zu vielen Wörtern. Hastur vor 7 Jahren 0

1 Antwort auf die Frage

1
Hastur

Lassen Sie uns Ihre in Ihrem Verzeichnis das Vorhandensein der Dateien übernehmen 1.a, 2.a, 3.a.

Mit dem Befehl

ls *.a | xargs -I{} echo {} | sed 's/.a//' 

Sie haben keine Subshells, die Ausgabe von lswird in xargsdie Pipes geleitet, die ihre Ersetzungen vornehmen. Dann wird die Ausgabe zu Pipe geleitet sed. Von hier aus dein erstes Ergebnis.

Mit dem Befehl

ls *.a | xargs -I{} bash -c "echo {} $(echo {} | sed 's/.a//')" 

Du hast ein neues Element $(echo {} | sed 's/.a//').

Es wird erweitert und wird

echo {} # -- > {} echo {} | sed 's/.a//' # -- > {} again the same. 

So kann Ihr Befehl als neu geschrieben werden

 ls *.a | xargs -I{} bash -c "echo {} {} " 

das gibt deine zweite Ausgabe.

Wie eben eben auch Gast in seinem Kommentar debuggen Sie Ihr Skript [ 1 ] (oder Kommando); mit set -xIhnen die Debug in der aktuellen Shell oder Script aktivieren und mit set +xIhnen deaktivieren:

set -x  ls *.a | xargs -I{} bash -c "echo {} $(echo {} | sed 's/.a//')" set +x  

und du wirst jeden Schritt sehen

+ ls --color=auto 1.a 2.a 3.a ++ echo '{}' ++ sed s/.a// + xargs '-I{}' bash -c 'echo {} {}' 1.a 1.a 2.a 2.a 3.a 3.a 
Gibt es eine Problemumgehung? stas vor 7 Jahren 0
Welche Ausgabe möchten Sie haben? Was war deine Idee? Hastur vor 7 Jahren 0
Debuggenverfolgung stimmt nicht überein> _ < guest-vm vor 7 Jahren 0
@stas `ls * .a | xargs -I {} bash -c "echo {} \ $ (echo {} | sed's / .a // ')" ` guest-vm vor 7 Jahren 0
@Gest `> _ <` Danke, ich habe den anderen Befehl kopiert ... Ich wurde von einer _querelle_ auf einer anderen [Frage] abgelenkt (http://superuser.com/q/1093111/257269) ... Hastur vor 7 Jahren 0