นี่เป็นข้อ จำกัด find
ของ มาตรฐาน POSIXระบุว่าสถานะการกลับมาของfind
คือ 0 เว้นแต่จะมีข้อผิดพลาดเกิดขึ้นในขณะที่ภายในไดเรกทอรี; สถานะการส่งคืนของคำสั่งที่ดำเนินการจะไม่ถูกป้อนเข้าไป
คุณสามารถทำให้คำสั่งเขียนสถานะลงในไฟล์หรือไปที่ descriptor:
find_status_file=$(mktemp findstatus)
: >"$find_status_file"
find … -exec sh -c 'trap "echo \$?" EXIT; invalid_command "$0"' {} \;
if [ -s "$find_status_file" ]; then
echo 1>&2 "An error occurred"
fi
rm -f "$find_status_file"
อีกวิธีที่คุณค้นพบคือการใช้ xargs xargs
คำสั่งเสมอประมวลผลไฟล์ทั้งหมด แต่กลับสถานะ 1 ถ้ามีคำสั่งผลตอบแทนสถานะภัณฑ์
find … -print0 | xargs -0 -n1 invalid_command
อีกวิธีหนึ่งคือการหลีกเลี่ยงfind
และใช้การวนซ้ำแบบซ้ำในเชลล์แทน: **/
หมายถึงความลึกของไดเรกทอรีย่อย ต้องใช้เวอร์ชัน 4 หรือสูงกว่าของ bash; macOS ค้างอยู่ที่รุ่น 3.x ดังนั้นคุณต้องติดตั้งจากคอลเลกชันพอร์ต ใช้set -e
เพื่อหยุดสคริปต์ในคำสั่งแรกคืนสถานะที่ไม่ใช่ศูนย์
shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done
ระวังว่าใน bash 4.0 ถึง 4.2 มันจะทำงานได้ แต่ traverses ลิงก์สัญลักษณ์ไปยังไดเร็กตอรี่ซึ่งมักจะไม่ต้องการ
หากคุณใช้ zsh แทนทุบตีการวนซ้ำแบบซ้ำจะออกจากกล่องโดยไม่มี gotchas Zsh พร้อมใช้งานตามค่าเริ่มต้นใน OSX / macOS ใน zsh คุณสามารถเขียนได้
set -e
for x in **/*.xml; do invalid_command "$x"; done
xargs
วิธีการทำงานโดยทั่วไป แต่อย่างใดแบ่งในbash -c
คำสั่ง ตัวอย่างเช่นfind . -name '*.xml' -print0 | xargs -0 -n 1 -I '{}' bash -c "foo {}"
. นี่จะถูกดำเนินการหลายครั้งในขณะที่find . -name '2*.xml' -print0 | xargs -0 -n 1 -I '{}' foo {}
ถูกดำเนินการเพียงครั้งเดียวและล้มเหลว มีความคิดอะไรไหม