ใช้คำสั่งต่อไปนี้ใครช่วยอธิบายหน่อยได้ไหมว่าอะไรคือจุดประสงค์สำหรับการจัดฟันส่วนปลาย ({}) และเครื่องหมายบวก (+)?
และคำสั่งจะทำงานแตกต่างกันอย่างไรหากถูกแยกออกจากคำสั่ง
find . -type d -exec chmod 775 {} +
ใช้คำสั่งต่อไปนี้ใครช่วยอธิบายหน่อยได้ไหมว่าอะไรคือจุดประสงค์สำหรับการจัดฟันส่วนปลาย ({}) และเครื่องหมายบวก (+)?
และคำสั่งจะทำงานแตกต่างกันอย่างไรหากถูกแยกออกจากคำสั่ง
find . -type d -exec chmod 775 {} +
คำตอบ:
วงเล็บปีกกาจะถูกแทนที่ด้วยผลลัพธ์ของfindคำสั่งและchmodจะถูกรันบนแต่ละอัน +ทำให้findพยายามที่จะทำงานตามคำสั่งน้อยที่สุด (ดังนั้นchmod 775 file1 file2 file3เมื่อเทียบกับchmod 755 file1 , chmod 755 file2, chmod 755 file3) หากไม่มีคำสั่งก็จะทำให้เกิดข้อผิดพลาด นี่คือทั้งหมดที่อธิบายในman find:
-exec command ;
ดำเนินการคำสั่ง ; เป็นจริงถ้าส่งคืนสถานะ 0 อาร์กิวเมนต์ทั้งหมดต่อไปนี้ที่จะ
findถูกนำไปเป็นอาร์กิวเมนต์ของคำสั่งจนกว่าอาร์กิวเมนต์ประกอบด้วย ';' สตริง '{}' จะถูกแทนที่ด้วยชื่อไฟล์ปัจจุบันกำลังดำเนินการทุกที่มันเกิดขึ้นในการขัดแย้งกับคำสั่งที่ไม่เพียงfindแต่ในการขัดแย้งที่มันเป็นคนเดียวในขณะที่บางรุ่น ...
-exec command {} +
การ
-execกระทำที่แตกต่างนี้รันคำสั่งที่ระบุในไฟล์ที่เลือก แต่บรรทัดคำสั่งจะถูกสร้างโดยการต่อท้ายชื่อไฟล์ที่เลือกแต่ละชื่อที่ท้าย จำนวนการเรียกใช้คำสั่งทั้งหมดจะน้อยกว่าจำนวนไฟล์ที่ตรงกัน ...
นอกจากคำตอบของ terdon แล้ว
-exec …ต้องถูกยกเลิกด้วยเครื่องหมายอัฒภาค ( ;) หรือเครื่องหมายบวก ( +) เซมิโคลอนเป็นอักขระพิเศษในเชลล์ (หรืออย่างน้อยทุกเชลล์ที่ฉันเคยใช้) ดังนั้นถ้าจะใช้เป็นส่วนหนึ่งของfindคำสั่งมันจะต้องหลบหนีหรืออ้างถึง ( \;,";"หรือ';')ด้วย-exec … ;การ{}สตริงอาจปรากฏจำนวนครั้งใด ๆ ในคำสั่งให้รวมศูนย์หรือสองคนหรือมากกว่าในตำแหน่งใด ๆ
ดูนี้
สำหรับตัวอย่างของทำไมคุณอาจต้องการที่จะทำโดยไม่ต้องใช้-exec {}
มีสองคนหรือมากกว่าที่ปรากฏจะเป็นประโยชน์อย่างยิ่งเพราะใน (อย่างน้อย) บางรุ่นfindที่{}ไม่จำเป็นต้องเป็นคำด้วยตัวเอง; มันสามารถมีตัวละครอื่น ๆ ที่จุดเริ่มต้นหรือจุดสิ้นสุด; เช่น,
find . -type f -exec mv {} {}.bak ";"
ด้วย-exec … +การ{}สตริงจะต้อง+ปรากฏเป็นอาร์กิวเมนต์สุดท้ายก่อน คำสั่งเช่น
find . -name "*.bak" -exec mv {} backup_folder +
ผลลัพธ์ในfind: missing argument to ‘-exec’ข้อความแสดงข้อผิดพลาดปริศนา
วิธีหลีกเลี่ยงปัญหาสำหรับสิ่งนี้เฉพาะสำหรับคำสั่งcpและmv
find . -name "*.bak" -exec mv -t backup_folder {} +
หรือ
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
{}จะต้องเป็นคำด้วยตัวเอง; มันไม่สามารถมีตัวละครอื่น ๆ ที่จุดเริ่มต้นหรือจุดสิ้นสุด และใน (อย่างน้อย) บางเวอร์ชั่นfindคุณอาจมีมากกว่าหนึ่ง{}รุ่น
หมายเหตุด้านสุขภาพ: คุณสามารถพูดได้
หา -name "* .sh" -type f -executable -exec {} ตัวเลือก args ที่นี่ ";"
เพื่อเรียกใช้สคริปต์แต่ละตัวของคุณ แต่
หา -name "* .sh" -type f -executable -exec {} +
รันหนึ่งในสคริปต์ของคุณด้วยชื่อของคนอื่น ๆ ทั้งหมดเป็นพารามิเตอร์ มันคล้ายกับว่า
./*.sh
เป็นคำสั่งของเชลล์ยกเว้นfindไม่ได้รับประกันว่ามันจะเรียงลำดับผลการค้นหาของคุณจึงไม่รับประกันของการทำงานaaa.sh
(ตามลำดับตัวอักษรแรกของคุณ*.shไฟล์) ./*.shที่คุณจะเป็นกับการทำงาน
แง่มุมfindที่อาจไม่ชัดเจนสำหรับผู้เริ่มต้นคือบรรทัดคำสั่งคือคำสั่งที่ใช้งานได้ในภาษาอาร์เคน ตัวอย่างเช่น,
find . -name "*.sh" -type f -executable -print
วิธี
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
หรือเพียงแค่
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
-คำหลักบางคำเป็นทั้งการกระทำที่ปฏิบัติการได้และการทดสอบ โดยเฉพาะอย่างยิ่งนี่เป็นเรื่องจริงสำหรับ-exec … ;; ตัวอย่างเช่น,
find . -type f -exec grep -q cat {} ";" -print
แปลเป็น
สำหรับแต่ละไฟล์
ถ้ามันเป็นไฟล์ธรรมดา (เช่นไม่ใช่ไดเรกทอรี)
แล้วก็
ดำเนินการ grep -q cat ชื่อไฟล์
หากกระบวนการประสบความสำเร็จ (เช่นออกจากสถานะ 0)
แล้วก็
พิมพ์ชื่อไฟล์
จบถ้า
จบถ้า
ปลายวน
ซึ่งจะพิมพ์ชื่อของไฟล์ทั้งหมดที่มีสตริง“ cat” และในขณะที่นี่คือสิ่งที่grepสามารถทำได้ด้วยตัวเอง (กับตัวเลือก (ตัว-lพิมพ์เล็กL)) มันจะมีประโยชน์ที่จะใช้มันfindเพื่อค้นหาไฟล์ที่มีสตริงที่แน่นอนและมีขนาดที่แน่นอนและเป็นเจ้าของโดยเจ้าของบางราย และถูกแก้ไขในช่วงเวลาหนึ่ง….
-exec … +แต่นี้ไม่ได้ทำงานให้ เนื่องจาก-exec … +เรียกใช้งานคำสั่งเดียวสำหรับไฟล์หลาย ๆ ไฟล์มันไม่สมเหตุสมผลเลยที่จะใช้มันเป็นเงื่อนไขตรรกะภายในfor each file …ลูป
findโดยทั่วไปแล้วจะออกด้วยสถานะการออกเป็น 0 เว้นแต่คุณจะให้อาร์กิวเมนต์ที่ไม่ถูกต้องหรือพบกับไดเรกทอรีที่ไม่สามารถอ่านได้ แม้ว่าโปรแกรมที่คุณดำเนินการจะล้มเหลว (ออกจากสถานะออกที่ไม่เป็นศูนย์),
findจะออกโดยมีสถานะออกเป็น 0
ยกเว้น ว่าโปรแกรมที่คุณดำเนินการ-exec … +ล้มเหลว (ออกด้วยสถานะออกไม่เป็นศูนย์)
findจะออกจาก ด้วยสถานะการออกที่ไม่เป็นศูนย์นอกเหนือจากหนึ่งล้านเวอร์ชันfind(1)
และทดสอบสิ่งที่findเกิดขึ้นจริงกับสองระบบแล้ว
ข้อมูลจำเพาะของ Open Group Base Issue 7, 2013 Edition ยัง
ให้ข้อมูลบางอย่างเกี่ยวกับสิ่งที่findต้องทำอาจและต้องไม่ทำ
... -exec mv {} {}.bak ...นั้นไม่ได้รับประกันว่าจะทำงานได้อย่างที่คาดไว้กับfindการใช้งานทั้งหมด สถานะมาตรฐาน POSIX{}จะต้องปรากฏขึ้นตามลำพังเพื่อให้ได้รับการยอมรับเสมอมิฉะนั้นลักษณะการทำงานมีอิสระที่จะไม่เปลี่ยนแปลงอักขระหรือแทนที่ด้วยชื่อพา ธ ในกรณีที่อดีตคำสั่งทั้งหมดของคุณเป็นหลักจะลบไฟล์ทั้งหมด แต่คนสุดท้ายพบ ...