Perbedaan antara "xargs" dan substitusi perintah?

14

Dalam banyak kasus saya menggunakan pengganti perintah xargs. Misalnya rm $(ls)sama denganls | xargs rm

Apa sebenarnya perbedaan di antara mereka?

Saya pikir salah satu perbedaannya adalah bahwa substitusi perintah berjalan di subkulit saat xargsberjalan di shell saat ini tetapi saya tidak yakin.

Harap sebutkan perbedaannya.

Sinoosh
sumber

Jawaban:

9

Satu perbedaan adalah bahwa ketika menggunakan substitusi perintah bukannya pipa, ukuran data yang dikirimkan dibatasi oleh ukuran buffer perintah, sehingga terpotong dalam beberapa kasus tanpa peringatan. Ini juga berarti bahwa seluruh output perintah harus diproduksi, dan disimpan dalam memori, sebelum diteruskan ke perintah berikutnya, jadi untuk output besar Anda dapat menggunakan lebih banyak memori daripada yang diperlukan.

Masalah lain dengan metode pertama adalah bahwa output dibagi pada spasi putih, jadi Anda tidak bisa menangani nama file dengan spasi di dalamnya. xargsjuga dipengaruhi oleh masalah spasi putih, tetapi bisa diperbaiki dengan mengubah pembatas yang digunakan. Untuk menangani nama file dengan benar, Anda harus menggunakan byte nol sebagai pembatas pada contoh kedua.

Masalah ketiga adalah bahwa gumpalan diperluas, jadi jika file memiliki tanda bintang atau tanda tanya dalam namanya, akan ada hasil yang tidak terduga.

Anda dapat menemukan diskusi yang bagus tentang masalah ini di sini: http://mywiki.wooledge.org/ParsingLs

Sintaks yang benar adalah

echo rm *

atau jika Anda harus menggunakan xargs,

find . -maxdepth 1 -print0 | xargs -0 echo rm

Hapus echoketika output terlihat benar.

pengguna000001
sumber
1
@Sinoosh: xargsjuga berjalan dalam subkulit karena pipa, kecuali jika Anda mengaktifkan shopt -s lastpipe, dalam hal ini akan berjalan di shell saat ini. Saya tidak berpikir bahwa menjalankan dalam subkulit adalah masalah meskipun dalam kasus ini, karena Anda tidak mengubah variabel apa pun.
user000001
1
@Sinoosh: Untuk menyampaikan argumen satu per satu Anda dapat menggunakan -lflag, seperti find . -maxdepth 1 -print0 | xargs -0 -l rm. Untuk pertanyaan kedua, Anda tidak dapat menggunakan lsdengan xargs -0karena ls tidak membagi output pada null bute, tetapi dengan baris baru (yang valid dalam nama file BTW)
user000001
1
@Sinoosh: Bukan paragraf pertama, tetapi paragraf kedua: xargs tanpa -0opsi menderita masalah spasi putih.
user000001
1
Baca man xargs, gunakan echountuk pengujian, bukan rm. xargsmemungkinkan kita melampaui batas shell (beberapa buffer dibatasi hingga 65K, daftar nama file tidak).
waltinator
1
@Sinoosh: Saya tidak memiliki referensi yang berguna, tetapi Anda dapat mengetik xargs --show-limitsdan Anda akan melihat batas yang ditetapkan pada sistem Anda,
user000001