การใช้วงเล็บปีกกา {} เป็นอาร์กิวเมนต์ของคำสั่งและตัวเลือกต่างๆ


11

ตัวอย่าง

ฉันเพิ่งพบตัวอย่างของการใช้วงเล็บปีกกาคู่{}โดยไม่มีอะไรในระหว่างวงเล็บเปิดและปิดเป็นอาร์กิวเมนต์ของคำสั่งและแม้แต่กับตัวเลือก:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

ไม่มีเอกสารประกอบ

ปัญหาของฉันคือฉันไม่สามารถหาเอกสารในGNU Bash Manualที่อธิบายการใช้งาน{}ในบริบทเช่นในตัวอย่างข้างต้น

ผมไม่คิดว่ามันเป็นขยายตัวพารามิเตอร์${}เพราะเครื่องหมายดอลลาร์ต้องนำหน้าวงเล็บปิดล้อมในการขยายตัวพารามิเตอร์ในขณะที่

มันไม่สามารถเป็นส่วนขยายรั้งได้เช่นกันเพราะใช้รูปแบบของ{x..y[..incr]}ที่ไหนxและyไม่จำเป็น

นอกจากนี้ยังไม่สามารถจัดกลุ่มคำสั่งได้เนื่องจาก{}ใช้เป็นอาร์กิวเมนต์

คำถาม

  1. วงเล็บปีกกาคู่คู่{}หมายถึงอะไรโดยทั่วไปในฐานะอาร์กิวเมนต์สำหรับคำสั่งใด ๆ ที่ยอมรับมัน

  2. ฉันจะหาเอกสารที่อธิบายการใช้งานของ{}อาร์กิวเมนต์ได้ที่ไหน


บางคำสั่งมีตัวเลือกนี้{}- หมายถึงtargetsการดำเนินการกับfindคำสั่งมันเป็นลบ / rmพบไฟล์
Tuyen Pham

คำตอบ:


16

วงเล็บปีกกาเหล่านี้ถูกปล่อยทิ้งไว้โดยลำพัง พวกเขาเป็นของfindและxargsตามลำดับและอธิบายไว้ในหน้าคนของพวกเขา

man find

-exec คำสั่ง ;

ดำเนินการคำสั่ง ; เป็นจริงถ้าส่งคืนสถานะ 0 ข้อโต้แย้งต่อไปนี้ทั้งหมดเพื่อหาจะถูกนำไปเป็นข้อโต้แย้งคำสั่งจนกว่าจะมีการโต้แย้งซึ่งประกอบด้วย;พบ สตริง{}จะถูกแทนที่ด้วยชื่อไฟล์ปัจจุบันกำลังดำเนินการทุกที่มันเกิดขึ้นในการขัดแย้งกับคำสั่งที่ไม่เพียง findแต่ในการขัดแย้งที่มันเป็นคนเดียวในขณะที่บางรุ่น ทั้งสองสิ่งก่อสร้างเหล่านี้อาจจำเป็นต้องหลบหนี (ด้วย\) หรืออ้างเพื่อป้องกันพวกเขาจากการขยายตัวโดยเปลือก ดูส่วนตัวอย่างสำหรับตัวอย่างของการใช้-execตัวเลือก คำสั่งที่ระบุ ถูกเรียกใช้ครั้งเดียวสำหรับแต่ละไฟล์ที่ตรงกัน คำสั่งจะถูกดำเนินการในไดเรกทอรีเริ่มต้น มีปัญหาด้านความปลอดภัยที่หลีกเลี่ยงไม่ได้รอบการใช้-exec แอคชัน คุณควรใช้-execdirตัวเลือกแทน

-exec คำสั่ง {} +

การ-execกระทำที่แตกต่างนี้รันคำสั่งที่ระบุในไฟล์ที่เลือก แต่บรรทัดคำสั่งจะถูกสร้างโดยการต่อท้ายชื่อไฟล์ที่เลือกแต่ละชื่อที่ท้าย จำนวนการร้องขอคำสั่งทั้งหมดจะน้อยกว่าจำนวนไฟล์ที่ตรงกัน บรรทัดคำสั่งสร้างขึ้นในลักษณะเดียวกับที่xargsสร้างบรรทัดคำสั่ง อนุญาตหนึ่งอินสแตนซ์ของ{}ภายในคำสั่ง คำสั่งจะถูกดำเนินการในไดเรกทอรีเริ่มต้น หากfindพบข้อผิดพลาดบางครั้งอาจทำให้เกิดการออกทันทีดังนั้นบางคำสั่งที่รอดำเนินการอาจไม่สามารถทำงานได้เลย ชุดตัวเลือกนี้-execจะคืนค่าเป็นจริงเสมอ

-execdir คำสั่ง ;

-execdir คำสั่ง {} +

ไลค์ -execแต่คำสั่งที่ระบุรันจากไดเร็กทอรีย่อยที่มีไฟล์ที่จับคู่ซึ่งโดยปกติจะไม่ใช่ไดเร็กทอรีที่คุณเริ่มต้นค้นหา วิธีนี้มีความปลอดภัยมากขึ้นสำหรับการเรียกใช้คำสั่งเนื่องจากจะหลีกเลี่ยงสภาวะการแข่งขันในระหว่างการแก้ปัญหาพา ธ ไปยังไฟล์ที่ตรงกัน เช่นเดียวกับการ -exec ดำเนินการ + รูปแบบ -execdir จะสร้างบรรทัดคำสั่งเพื่อประมวลผลไฟล์ที่ตรงกันมากกว่าหนึ่งไฟล์ แต่การเรียกใช้คำสั่งที่กำหนดใด ๆ จะแสดงรายการไฟล์ที่มีอยู่ในไดเรกทอรีย่อยเดียวกันเท่านั้น หากคุณใช้ตัวเลือกนี้คุณต้องแน่ใจว่า$PATHตัวแปรสภาพแวดล้อมของคุณไม่ได้อ้างอิง.; ผู้โจมตีจะสามารถเรียกใช้คำสั่งใด ๆ -execdirที่พวกเขาต้องการโดยออกจากไฟล์ที่เหมาะสมที่มีชื่อในไดเรกทอรีที่คุณจะเรียกใช้ เช่นเดียวกับการมีรายการ$PATHที่ว่างเปล่าหรือที่ไม่ใช่ชื่อไดเรกทอรีแน่นอน หากfindพบข้อผิดพลาดบางครั้งอาจทำให้เกิดการออกทันทีดังนั้นบางคำสั่งที่รอดำเนินการอาจไม่สามารถทำงานได้เลย ผลลัพธ์ของการดำเนินการขึ้นอยู่กับว่ามี+การใช้;ตัวแปรหรือ -execdir คำสั่ง {} +ส่งกลับค่าจริงเสมอในขณะที่-execdir คำสั่ง {} ;กลับเป็นจริงเฉพาะในกรณีที่คำสั่งกลับ 0

man xargs

-I แทนที่-Str

แทนที่การเกิดขึ้นของreplace-strในอาร์กิวเมนต์เริ่มต้นด้วยชื่อที่อ่านจากอินพุตมาตรฐาน นอกจากนี้ช่องว่างที่ไม่มีเครื่องหมายอัญประกาศจะไม่ยุติรายการอินพุต ตัวคั่นเป็นอักขระขึ้นบรรทัดใหม่แทน นัย-xและ-L 1.

-i[ replace-str ], --replace[ =replace-str ]

ตัวเลือกนี้เป็นคำพ้องสำหรับ-Iแทนที่-Strถ้าเปลี่ยน-Strระบุไว้ ถ้าเปลี่ยน-Str-I{}อาร์กิวเมนต์จะหายไปผลที่ออกมาเป็นเช่นเดียวกับ ตัวเลือกนี้เลิกใช้แล้ว ใช้-Iแทน

แก้ไข: และนี่ทำไม bash ละเว้นวงเล็บปีกกาเหล่านั้น:

man bash

{ รายการ; }

รายการ ถูกดำเนินการอย่างง่ายในสภาพแวดล้อมเชลล์ปัจจุบัน รายการจะต้องถูกยกเลิกด้วยการขึ้นบรรทัดใหม่หรืออัฒภาค สิ่งนี้เรียกว่าคำสั่งกลุ่ม สถานะการส่งคืนคือสถานะการออกของรายการ โปรดทราบว่าแตกต่างจาก metacharacters (และ) , {และ}เป็นคำสงวนและต้องเกิดขึ้นเมื่อคำที่สงวนไว้ได้รับอนุญาตให้จดจำได้ เนื่องจากไม่ทำให้เกิดการแบ่งคำจึงต้องแยกออกจากรายการด้วยช่องว่างหรือเชลล์ตัวอักขระอื่น

สำหรับการเน้น: รายการต้องถูกยกเลิกด้วยการขึ้นบรรทัดใหม่หรืออัฒภาค


1
ขอบคุณ! ฉันรำคาญว่าใครก็ตามที่เขียนman xargsไม่ได้รำคาญที่จะอธิบายสิ่งที่{}จริงหมายถึงไม่ได้เปลี่ยนเส้นทางผู้แต่ง (ไม่มีเล่นสำนวนเจตนา) อ่านคำอธิบายในมนุษย์หน้าของ-exec find
Niko Gambt

@NikoGambt - ฉันเห็นอกเห็นใจ ...
ทิงค์

5
@NikoGambt ดี {} ไม่ได้มีความหมายอะไรกับ xargs ยกเว้นการเป็นค่าเริ่มต้นสำหรับ -i ซึ่งเลิกใช้แล้ว ฉันไม่แน่ใจว่าคำอธิบายใดที่จำเป็นเกินกว่านั้น ในตัวอย่างที่คุณโพสต์อาจเป็นเช่นxargs -Iab echo abนั้น มันเป็นทางเลือกโดยพลการอย่างแท้จริง
Random832

@ Random832 หลังจากทำการทดสอบเพิ่มเติมด้วย-Iตอนนี้ฉันเข้าใจว่าตัวเลือกนั้นทำอะไรได้จริง ใช่{}เป็นเรื่องที่คุณพูด If the replace-str argument is missing, the effect is the same as -I{}ผมสับสนเพียงแค่คำอธิบาย หาก-Iได้โดยไม่ต้องโต้แย้งเหมือนกับ-I{}แล้วจะผลิตผลเช่นเดียวกับการทำงานcat foo | xargs -I echo {} cat foo | xargs -I{} echo {}อย่างไรก็ตามพวกเขาไม่เหมือนกัน อดีตคือข้อผิดพลาดและสิ่งที่ทำให้ฉันสับสนมากยิ่งขึ้นก็คือข้อความแสดงข้อผิดพลาดxargs: {}: No such file or directoryแต่นั่นเป็นเพียงการดำเนินการ
Niko Gambt

1
@NikoGambt -I(ตัวพิมพ์ใหญ่ I) ไม่สามารถรันได้หากไม่มีอาร์กิวเมนต์ อาร์กิวเมนต์เป็น-I echoนี่คือความแตกต่างหลักระหว่าง-Iและ-i(และเหตุผล -i ถูกคัดค้านเนื่องจากตัวเลือกที่มีอาร์กิวเมนต์ที่ไม่จำเป็นต้องใช้เป็นเรื่องแปลกและสับสน)
สุ่ม 832
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.