ป้องกัน xargs จากการออกจากข้อผิดพลาด


27

ตามหน้า man, xargs จะออกหากหนึ่งในบรรทัดการดำเนินการออกจากกับข้อผิดพลาด 255:

หากการเรียกใช้คำสั่งออกจากสถานะ 255, xargs จะหยุดทันทีโดยไม่ต้องอ่านอินพุตเพิ่มเติมใด ๆ ข้อความแสดงข้อผิดพลาดออกมาใน stderr เมื่อเกิดเหตุการณ์นี้

ฉันจะได้รับ xargs เพื่อไม่ทำเช่นนี้ได้อย่างไร

ฉันมีงานแบ็ตช์แบบ 1500 หรือมากกว่านั้นที่ฉันต้องการรันครั้งละ 50 บรรทัด ฉันพบว่ามันกำลังจะตายในบางบรรทัดและไม่ได้ทำงานให้เสร็จ ไม่ดี!

คำถามที่ดียิ่งขึ้นคำถามที่อธิบายสิ่งที่ฉันพยายามทำคือ:

ฉันจะรันสคริปต์แบทช์ 1,500 บรรทัดได้ครั้งละ 50 บรรทัดเพื่อที่จะไม่ออกจากงานที่อยู่ตรงกลางและเพื่อให้ผลลัพธ์ถูกจับไปยังไฟล์บันทึกบางชนิด?

คำตอบ:


12

คุณสามารถรวมสคริปต์ perl ด้วยสคริปต์ทุบตีง่ายๆอีก:

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

สิ่งนี้จะเรียกใช้คำสั่งจริงผ่านพารามิเตอร์ทั้งหมดที่คุณส่งไปยังคำสั่งปลอมนี้และจะส่งคืนรหัสการออก 0 เสมอ (ซึ่งหมายความว่าจะประสบความสำเร็จเสมอ) และ xargs จะไม่หยุดกับสิ่งนี้



9

คุณสามารถเขียนคำร้องขอ xargs ของคุณเพื่อปกปิดรหัสที่ส่งคืนของบรรทัดคำสั่งของคุณ ด้วยสิ่งต่อไปนี้คุณxargsจะไม่เห็นรหัสทางออกส่งกลับโดยsomecommand :

xargs sh -c "somecommand || :"

ฉันได้คำตอบที่ดี: ตรวจสอบให้แน่ใจว่าคำสั่งที่ดำเนินการแล้วไม่ออกด้วยสถานะ 255! รายละเอียดเพิ่มเติม คำสั่งที่กำลังประมวลผลเป็นสคริปต์ Perl มีการใช้ฟังก์ชัน Perl die () ในหลายแห่งเพื่อออกจากระบบหากมีข้อผิดพลาดร้ายแรงเกิดขึ้น (เช่นไม่สามารถเชื่อมต่อกับฐานข้อมูล) อย่างไรก็ตาม die () ออกจากสถานะข้อผิดพลาด 255 เสมอวิธีแก้ปัญหาในกรณีนี้คือแทนที่ die () ด้วยการพิมพ์และออก () พร้อมด้วยรหัสข้อผิดพลาดที่สมเหตุสมผล ("1" ทำงานในกรณีนี้)
JDS

6

เพิ่งพบคำตอบที่สนุกสำหรับสิ่งนี้แม้ว่าความมีประโยชน์ของมันจะขึ้นอยู่กับคำสั่งที่คุณพยายามเรียกใช้

หากคุณใช้ xargs เพื่อรวบรวมรายการคำสั่งโดยทั่วไปคุณสามารถรับลักษณะการทำงานนี้ได้โดยการบอกให้ xargs ทำการ echo คำสั่งจากนั้น piping to bash

ตัวอย่างเช่นหากคุณพยายามลบรายการสิ่งต่าง ๆ ที่อาจมีหรือไม่มีอยู่:

# 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

สิ่งนี้ทำงานได้เพราะอันดับแรก xargs เรียก echo เท่านั้นดังนั้นจึงไม่เห็นข้อผิดพลาดใด ๆ จากนั้นวินาทีเนื่องจากพฤติกรรมเริ่มต้นของ bash เพื่อดำเนินการต่อหลังจากคำสั่งที่ล้มเหลว

เพื่อให้เฉพาะเจาะจงมากขึ้นเกี่ยวกับกรณีของฉันฉันใช้สิ่งนี้เพื่อลบแอปพลิเคชันรุ่นเก่าออกจาก AWS ElasticBeanstalk ดังนี้:

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

4

งานก่อสร้างต่อไปนี้สำหรับฉัน:

ls | xargs -I % svn upgrade %

แม้ว่าการอัพเกรด svn ล้มเหลวในองค์ประกอบบางส่วน


3

หากคุณใช้xargsกับfindใช้-execตัวเลือกfindแทน:

find . -name '*.log' -exec somecommand {} \;

1
หมอตำแย ฉันสามารถใช้งานได้ แต่ตัวเลือก -exec ไม่ได้ทำการดำเนินการแบบขนานโดยใช้ xargs และสามารถทำได้
JDS

2
ขอบคุณ - ฉันไม่รู้ว่าxargsสามารถเรียกใช้คำสั่งแบบขนาน เย็น. หากคุณต้องการลดจำนวนการเรียกใช้คำสั่งให้-execมี+พารามิเตอร์น้อยที่สุด
Roger Dahl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.