Mengapa xargs melewatkan argumen pertama saat meneruskan ke subkulit?


8

Mencari cara untuk memanggil lebih dari satu perintah dalam xargs one-liner, saya menemukan rekomendasi di findutils untuk memanggil shell dari xargs seperti ini:

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

Lucunya, jika saya menggunakan xargs seperti itu, untuk beberapa alasan ia melewatkan argumen pertama:

$ 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

Apakah ada yang salah dengan versi shell atau xargs saya? Apakah dokumentasi itu tidak akurat?

Menggunakan xargs (GNU findutils) 4.4.2 dan GNU bash, versi 4.3.11 (1) -release .

Jawaban:


13

Halaman manual [bash] mengatakan: " -c stringJika opsi -c hadir, maka perintah dibaca dari string. Jika ada argumen setelah string, mereka ditugaskan ke parameter posisi, dimulai dengan $ 0. " - Kuncinya adalah $ 0 ; itu berarti bahwa nama perintah akan menjadi argumen pertama.

seq 10 | xargs sh -c 'echo $@; echo $0' sh
1 2 3 4 5 6 7 8 9 10
sh

Oh begitu! jadi itu sebabnya dokumen menuliskannya movedi akhir contoh! Saya harus membaca dengan lebih cermat ... Terima kasih! =)
elias

11

Mengapa xargs melewatkan argumen pertama saat meneruskan ke subkulit?

Tidak. Bash memberikan argumen pertama menjadi $ 0:

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

$@ekspansi ke $1 $2 $3.... Akibatnya, nilai $0tidak termasuk dalam $@.


Penjelasan ini jauh lebih jelas daripada @ Janis, tetapi jawaban Janis termasuk solusi yang baik untuk masalah ini.
alexis
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.