-exec
คำสั่งจะต้องถูกยกเลิกด้วย;
(ดังนั้นคุณจะต้องพิมพ์\;
หรือ';'
เพื่อหลีกเลี่ยงการ interpretion จากเปลือก) +
หรือ ข้อแตกต่างคือด้วย;
คำสั่งจะเรียกหนึ่งครั้งต่อไฟล์โดยเรียกว่าคำสั่ง+
เพียงสองสามครั้ง (ปกติหนึ่งครั้ง แต่มีความยาวสูงสุดสำหรับบรรทัดคำสั่งดังนั้นจึงอาจถูกแยกออก) ด้วยชื่อไฟล์ทั้งหมด . ดูตัวอย่างนี้:
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
คำสั่งของคุณมีข้อผิดพลาดสองประการ:
ก่อนอื่นให้คุณใช้{};
แต่;
จะต้องเป็นพารามิเตอร์ของตัวเอง
&&
ประการที่สองคำสั่งปลายที่ คุณระบุ“ run find และหากประสบความสำเร็จให้ลบไฟล์ที่มีชื่อ{};
” หากคุณต้องการที่จะใช้สิ่งที่เปลือกในคำสั่งที่คุณต้องทำงานอย่างชัดเจนในเปลือกเช่น-exec
-exec sh -c 'ffmpeg ... && rm'
อย่างไรก็ตามคุณไม่ควรเพิ่ม {} ภายในคำสั่ง bash มันจะสร้างปัญหาเมื่อมีอักขระพิเศษ คุณสามารถส่งพารามิเตอร์เพิ่มเติมไปยังเชลล์แทนได้-c command_string
(ดูman sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
คุณเห็น$
สิ่งที่ประเมินโดยเชลล์ในตัวอย่างแรก ลองนึกภาพว่ามีไฟล์ชื่อ$(rm -rf /)
:-)
(หมายเหตุด้านข้าง: -
ไม่จำเป็น แต่ตัวแปรแรกหลังจากคำสั่งถูกกำหนดให้กับตัวแปร$0
ซึ่งเป็นตัวแปรพิเศษตามปกติที่มีชื่อของโปรแกรมที่กำลังเรียกใช้และการตั้งค่าพารามิเตอร์เป็นสิ่งสกปรกเล็กน้อยแม้ว่ามันจะชนะ อาจก่อให้เกิดอันตรายใด ๆ ที่นี่ดังนั้นเราจึงกำหนดให้เป็นเพียง-
และเริ่มต้นด้วย$1
)
ดังนั้นคำสั่งของคุณอาจเป็นอะไรก็ได้
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
แต่มีวิธีที่ดีกว่าคือ หาการสนับสนุนand
และดังนั้นคุณอาจจะทำสิ่งที่ชอบor
find -name foo -or -name bar
แต่นั่นก็ยังทำงานได้ด้วย-exec
ซึ่งประเมินว่าเป็นจริงหากคำสั่งออกจากที่สำเร็จและเป็นเท็จหากไม่ ดูตัวอย่างนี้:
$ ls
false true
$ find * -exec {} \; -and -print
true
มันจะทำงานพิมพ์ถ้าคำสั่งก็ประสบความสำเร็จซึ่งมันสำหรับแต่ไม่ได้สำหรับtrue
false
ดังนั้นคุณสามารถใช้สองคำสั่ง exec ที่ถูกล่ามโซ่ด้วย-and
และมันจะดำเนินการหลังถ้าอดีตถูกเรียกใช้ประสบความสำเร็จ