mencegah xarg dari berhenti karena kesalahan

27

Menurut halaman manual, xargs akan berhenti jika salah satu dari baris eksekusi keluar dengan kesalahan 255:

Jika ada pemanggilan perintah keluar dengan status 255, xargs akan segera berhenti tanpa membaca input lebih lanjut. Pesan kesalahan dikeluarkan pada stderr ketika ini terjadi.

Bagaimana saya bisa mendapatkan xargs untuk tidak melakukan ini?

Saya memiliki 1.500 pekerjaan batch yang ingin saya jalankan, 50 baris sekaligus. Saya menemukan bahwa itu selalu mati di jalur tertentu, dan tidak menyelesaikan pekerjaan. Tidak baik!

Pertanyaan yang lebih baik lagi, pertanyaan yang menggambarkan apa yang saya coba lakukan, adalah:

Bagaimana saya bisa menjalankan skrip batch 1500 baris, 50 baris sekaligus, sehingga tidak keluar dari pekerjaan di tengah, dan sehingga output ditangkap ke file log dari beberapa jenis?

JDS
sumber

Jawaban:

12

Anda bisa membungkus skrip perl dengan skrip bash sederhana lain:

#!/bin/bash
real-command "$@" || exit 0

Ini akan memanggil perintah-nyata lewat semua parameter yang Anda berikan ke perintah-palsu ini dan itu akan selalu mengembalikan kode keluar 0 (yang berarti selalu berhasil) dan xargs tidak akan pernah berhenti dengan ini.

pengguna842313
sumber
24

Mirip dengan larsksjawaban tetapi lebih eksplisit:

xargs sh -c "somecommand || true"
Filippo Vitale
sumber
menggunakan sh -cwors untukku!
hukeping
9

Anda bisa menulis permintaan xargs Anda untuk menutupi kode kembali dari baris perintah Anda. Dengan sesuatu seperti berikut ini, xargstidak akan pernah melihat kode keluar kembali dengan somecommand :

xargs sh -c "somecommand || :"
larsks
sumber
Saya telah datang dengan solusi yang baik: pastikan perintah yang sedang diproses tidak keluar dengan status 255! Detail Tambahan Perintah yang sedang diproses adalah skrip Perl. Fungsi Perl die () digunakan di beberapa tempat untuk keluar jika beberapa kesalahan kritis terjadi (mis. Tidak dapat terhubung ke database). Namun, die () selalu keluar dengan status kesalahan 255. Solusi dalam kasus ini adalah mengganti die () dengan kombinasi print dan exit (), bersama dengan kode kesalahan yang lebih masuk akal ("1" berhasil dalam kasus ini).
JDS
6

Baru saja menemukan jawaban yang menyenangkan untuk yang satu ini, meskipun kegunaannya akan tergantung pada perintah yang Anda coba jalankan.

Jika Anda menggunakan xargs pada dasarnya merakit daftar perintah, Anda bisa mendapatkan perilaku ini dengan mengatakan xargs untuk menggemakan perintah, kemudian memiping ke bash.

Misalnya, jika Anda mencoba menghapus daftar hal-hal yang mungkin ada atau tidak ada:

# presume this will fail in a similar way to your command
cat things_to_delete | xargs -n1 delete_command_that_might_exit

# instead echo the commands and pipe to bash
cat things_to_delete | xargs -n1 echo delete_command_that_might_exit | bash

Ini berfungsi karena, pertama, xargs hanya memanggil echo, jadi ia tidak akan melihat kesalahan. Kemudian kedua, karena perilaku default bash untuk melanjutkan eksekusi setelah pernyataan yang gagal.

Untuk lebih spesifik tentang kasus saya, saya menggunakan ini untuk menghapus banyak versi aplikasi lama dari AWS ElasticBeanstalk seperti:

aws elasticbeanstalk describe-application-versions --application-name myapp |\
jq -r '.ApplicationVersions | sort_by(.DateCreated) | .[0:-10] | .[].VersionLabel' |\
xargs -n1 \
  echo aws elasticbeanstalk delete-application-version \
       --delete-source-bundle --application-name myapp --version-label |\
bash
matschaffer
sumber
4

Pekerjaan konstruksi berikut untuk saya:

ls | xargs -I % svn upgrade %

Bahkan jika peningkatan svn gagal pada beberapa elemen, proses dilanjutkan

AndreyP
sumber
3

Jika Anda menggunakan xargsdengan find, gunakan -execopsi findsebagai gantinya:

find . -name '*.log' -exec somecommand {} \;
Roger Dahl
sumber
1
Howdy saya bisa menggunakan itu tetapi opsi -exec tidak memparalelkan operasi dengan cara menggunakan xargs dapat dan tidak
JDS
2
Terima kasih - saya tidak tahu itu xargsbisa menjalankan perintah secara paralel. Keren. Jika Anda hanya ingin meminimalkan jumlah permintaan perintah, -execmemiliki +parameter.
Roger Dahl