ใช้คำสั่งต่อไปนี้ใครช่วยอธิบายหน่อยได้ไหมว่าอะไรคือจุดประสงค์สำหรับการจัดฟันส่วนปลาย ({}) และเครื่องหมายบวก (+)?
และคำสั่งจะทำงานแตกต่างกันอย่างไรหากถูกแยกออกจากคำสั่ง
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{}
จะต้องปรากฏขึ้นตามลำพังเพื่อให้ได้รับการยอมรับเสมอมิฉะนั้นลักษณะการทำงานมีอิสระที่จะไม่เปลี่ยนแปลงอักขระหรือแทนที่ด้วยชื่อพา ธ ในกรณีที่อดีตคำสั่งทั้งหมดของคุณเป็นหลักจะลบไฟล์ทั้งหมด แต่คนสุดท้ายพบ ...