Pertimbangkan perintah ini:
ls /mydir/*.txt | xargs chown root
Tujuannya adalah mengubah pemilik semua file teks mydir
menjadi root
Masalahnya adalah jika tidak ada .txt
file di dalam mydir
xargs maka muncul kesalahan yang mengatakan tidak ada path yang ditentukan. Ini adalah contoh yang tidak berbahaya karena kesalahan sedang terjadi, tetapi dalam beberapa kasus, seperti dalam skrip yang perlu saya gunakan di sini, jalan kosong diasumsikan sebagai direktori saat ini. Jadi jika saya menjalankan perintah itu dari /home/tom/
maka jika tidak ada hasil untuk ls /mydir/*.txt
dan semua file di bawah /home/tom/
memiliki pemiliknya diubah menjadi root.
Jadi bagaimana saya bisa membiarkan xargs mengabaikan hasil kosong?
ls
untuk penggunaan program; lihat mywiki.wooledge.org/ParsingLsgit branch --merged | grep -v '^* ' | xargs git branch -d
Jawaban:
Untuk GNU
xargs
, Anda dapat menggunakan opsi-r
atau--no-run-if-empty
:sumber
brew install findutils
.findutils
, Tidakfileutils
.Pengguna xargs non-GNU dapat mengambil keuntungan dari
-L <#lines>
,-n <#args>
,-i
, dan-I <string>
:Perlu diingat bahwa xargs membagi garis di whitespace tetapi mengutip dan melarikan diri tersedia; RTFM untuk detail.
Juga, seperti yang disebutkan Doron Behar, solusi ini tidak portabel sehingga pemeriksaan mungkin diperlukan:
sumber
xargs
Anda tidak mendukung--no-run-if-empty
sakelar dan mencoba menjalankan argumen perintah tanpa input STDIN (ini adalah kasus di Solaris 10). Versi di unix lain mungkin mengabaikan daftar kosong (mis. AIX).echo '' | xargs -n1 echo blah
tidak melakukan apa-apa; sedangkanecho 'x' | xargs -n1 echo blah
mencetak "bla".ls /mydir/*.txt | xargs -n 1 -I {} chown root {}
disarankan oleh jawaban ini.echo '' | xargs -n1 echo blah
cetakanblah
dengan GNUxargs
.man xargs
kata--no-run-if-empty
.sumber
Dalam hal
xargs
, Anda dapat menggunakan-r
seperti yang disarankan, namun itu tidak didukung oleh BSDxargs
.Jadi sebagai solusi Anda dapat melewati beberapa file sementara tambahan, misalnya:
atau mengarahkan ulang stderrnya ke null (
2> /dev/null
), misPendekatan lain yang lebih baik adalah beralih pada file yang ditemukan menggunakan
while
loop:Lihat juga: Abaikan hasil kosong untuk xargs di Mac OS X
Harap perhatikan juga bahwa metode Anda untuk mengubah izin tidak terlalu bagus dan tidak disarankan. Tentunya Anda tidak harus menguraikan output
ls
perintah (lihat: Mengapa Anda tidak harus menguraikan output ls ). Terutama ketika Anda menjalankan perintah Anda dengan root, karena file Anda dapat terdiri dari karakter khusus yang dapat ditafsirkan oleh shell atau membayangkan file memiliki karakter spasi di sekitar/
, maka hasilnya bisa mengerikan.Karena itu Anda harus mengubah pendekatan Anda dan menggunakan
find
perintah, missumber
while IFS= read -r -d '' file
valid. Bisakah Anda jelaskan?Di OSX: Bash implementasi ulang
xargs
berurusan dengan-r
argumen, masukkan misalnya dalam$HOME/bin
dan tambahkan kePATH
:sumber
Ini adalah perilaku GNU xargs yang dapat ditekan dengan menggunakan -r, --no-run-if-empty.
Varian * BSD xargs memiliki behavoir ini secara default, jadi -r tidak diperlukan. Sejak FreeBSD 7.1 (dirilis pada Januari 2009) argumen -r diterima (penyihir tidak melakukan apa-apa) untuk alasan kompatiblity.
Saya pribadi lebih suka menggunakan longopts dalam skrip tetapi karena * BSD xargs tidak menggunakan longopts cukup gunakan "-r" dan xargs akan bertindak sama pada * BSD dan pada sistem linux
xargs pada MacOS (saat ini MacOS Mojave) sayangnya tidak mendukung argumen "-r".
sumber