Warum überspringt xargs das erste Argument, wenn es an die Subshell übergeben wird?

8

Auf der Suche nach einer Möglichkeit, mehr als einen Befehl in einem xargs- Einzeiler aufzurufen , fand ich in findutils die Empfehlung, die Shell von xargs wie folgt aufzurufen :

$ find ... | xargs sh -c 'command $@'

Das Lustige ist, wenn ich solche Xargs benutze, überspringt es aus irgendeinem Grund das erste Argument:

$ seq 10 | xargs bash -c 'echo $@'
2 3 4 5 6 7 8 9 10
$ seq 10 | xargs -n2 bash -c 'echo $@'
2
4
6
8
10

Stimmt etwas mit meiner Shell- oder Xargs-Version nicht? Ist diese Dokumentation ungenau?

Verwenden von xargs (GNU findutils) 4.4.2 und GNU bash, Version 4.3.11 (1) .

elias
quelle

Antworten:

13

Auf der Manpage [bash] heißt es: " -c stringWenn die Option -c vorhanden ist, werden Befehle aus der Zeichenfolge gelesen. Wenn nach der Zeichenfolge Argumente vorhanden sind, werden sie den Positionsparametern beginnend mit $ 0 zugewiesen. " - Der Schlüssel lautet $ 0 ;; Dies bedeutet, dass der Befehlsname das erste Argument sein soll.

seq 10 | xargs sh -c 'echo $@; echo $0' sh
1 2 3 4 5 6 7 8 9 10
sh
Janis
quelle
Oh, ich verstehe! Deshalb setzen die Dokumente das moveam Ende des Beispiels! Ich hätte genauer lesen sollen ... Danke! =)
Elias
11

Warum überspringt xargs das erste Argument, wenn es an die Subshell übergeben wird?

Das tut es nicht. Bash weist $ 0 das erste Argument zu:

$ seq 10 | xargs -n2 bash -c 'echo $0'
1
3
5
7
9

$@erweitert auf $1 $2 $3.... Folglich ist der Wert von $0nicht in enthalten $@.

John1024
quelle
Diese Erklärung ist viel klarer als die von @ Janis, aber Janis 'Antwort beinhaltet eine gute Lösung für das Problem.
Alexis