ฉันเจอคำสั่งต่อไปนี้:
sudo chown `id -u` /somedir
และฉันสงสัยว่า: ความหมายของ`
สัญลักษณ์คืออะไร ฉันสังเกตเห็นว่าขณะที่คำสั่งข้างต้นทำงานได้ดีคำสั่งด้านล่างไม่ทำงาน:
sudo chown 'id -u' /somedir
ฉันเจอคำสั่งต่อไปนี้:
sudo chown `id -u` /somedir
และฉันสงสัยว่า: ความหมายของ`
สัญลักษณ์คืออะไร ฉันสังเกตเห็นว่าขณะที่คำสั่งข้างต้นทำงานได้ดีคำสั่งด้านล่างไม่ทำงาน:
sudo chown 'id -u' /somedir
คำตอบ:
นี่คือbacktick backtick ไม่ใช่เครื่องหมายคำพูด มันมีความหมายพิเศษมาก ทุกสิ่งที่คุณพิมพ์ระหว่าง backticks จะถูกประเมิน (ดำเนินการ) โดยเชลล์ก่อนหน้าคำสั่งหลัก (เช่นchown
ในตัวอย่างของคุณ) และผลลัพธ์ของการดำเนินการนั้นจะถูกใช้โดยคำสั่งนั้นเช่นเดียวกับที่คุณพิมพ์ผลลัพธ์นั้น ณ ที่นั้น บรรทัดคำสั่ง.
ดังนั้นอะไร
sudo chown `id -u` /somedir
ทำงานอย่างมีประสิทธิภาพ (ขึ้นอยู่กับID ผู้ใช้ของคุณ ) คือ:
sudo chown 1000 /somedir
\ \ \ \
\ \ \ `-- the second argument to "chown" (target directory)
\ \ `-- your user ID, which is the output of "id -u" command
\ `-- "chown" command (change ownership of file/directory)
`-- the "run as root" command; everything after this is run with root privileges
ดูคำถามนี้เพื่อเรียนรู้ว่าทำไมในหลาย ๆ สถานการณ์จึงไม่ควรใช้ backticks
Btw หากคุณต้องการใช้ backtick อย่างแท้จริงเช่นในสตริงคุณสามารถหลบหนีได้โดยการวางแบ็กสแลช ( \
) ไว้ข้างหน้า
$()
ในสถานการณ์ส่วนใหญ่ก็ไม่ได้ทำให้ backticks เลวร้ายยิ่งสิ่งที่ เพื่อวัตถุประสงค์ในทางปฏิบัติเราต้องยอมรับว่าพวกมันเร็วกว่ามากในการพิมพ์บนบรรทัดคำสั่ง (2 การกดแป้นพิมพ์เมื่อเทียบกับอย่างน้อย 5 รวมถึงShift
)
$( )
แน่นอนว่าจะพิมพ์ได้ง่ายกว่า` `
คีย์บอร์ดภาษาฝรั่งเศสอย่างน้อย
ฉันต้องการเพิ่มคะแนนอีกเล็กน้อยที่นี่
backtick `…`
เรียกว่าจริงคำสั่งเปลี่ยนตัว วัตถุประสงค์ของการทดแทนคำสั่งคือการประเมินคำสั่งที่อยู่ภายใน backtick และให้ผลลัพธ์เป็นอาร์กิวเมนต์สำหรับคำสั่งจริง
ทดแทนคำสั่งที่สามารถทำได้ในสองวิธีหนึ่งคือการใช้$(…)
และอื่น ๆ `…`
คือ ทั้งสองทำงานเหมือนกัน แต่$(…)
รูปแบบเป็นวิธีที่ทันสมัยและมีความชัดเจนและอ่านง่ายขึ้น
และอื่น ๆ
sudo chown $(id -u) /somedir
สามารถเป็นที่ต้องการมากกว่าที่อื่น ๆ
และอีกหนึ่งสิ่งที่คุณจำเป็นต้องทราบที่นี่เป็นคำสั่งเปลี่ยนตัวความสัมพันธ์กับทุบตีอ้างกฎระเบียบดังกล่าวในทุบตีเอกสาร
หากการแทนที่ปรากฏภายในเครื่องหมายคำพูดคู่การแยกคำและการขยายชื่อไฟล์จะไม่ถูกดำเนินการกับผลลัพธ์
$(...)
ดีกว่ารัง
$()
และ"``"
ไม่ทำงานในลักษณะเดียวกัน
หนึ่งบันทึกของการชี้แจงที่ไม่ค่อยครอบคลุม:
Backticks (บางครั้งเรียกว่าหลุมฝังศพเพราะมันเป็นสำเนียงร่วมกันในภาษาฝรั่งเศสและภาษาอื่น ๆ ) แทนที่Standard Output เท่านั้นแต่ไม่ใช่ Standard Error
ดังนั้นเพื่อดำเนินการต่อตัวอย่างก่อนหน้านี้:
file `which hostname`
จะทำงานตามที่คาดไว้ แต่ใน:
file `which hostnameX`
which
จะส่งคืนข้อผิดพลาดและผลลัพธ์นั้นไปที่ข้อผิดพลาดมาตรฐานแทนที่จะแทนที่ลงบนบรรทัดคำสั่งถัดจากfile
; จะไม่มีเอาต์พุตมาตรฐานเลยซึ่งคุณสามารถยืนยันได้ด้วยการรัน:
which hostnameX
which hostnameX 2>/dev/null
ในกรณีนี้,
file `which hostnameX`
จะสร้างข้อความแสดงข้อผิดพลาดสองข้อความ (อันแรกอันเนื่องมาจากwhich hostnameX
และอันที่สองหลังจากอันก่อนเนื่องจากตัวไฟล์เองที่พบว่าชื่อไฟล์หายไปและดังนั้นคำสั่งทั้งหมด
จะลดลงเหลือเพียง:
file
ซึ่งแน่นอนว่าเป็นการใช้งานที่ไม่ดีและจะส่งคืนข้อผิดพลาดการใช้งาน
(ถ้าคุณต้องการตรวจสอบด้วยตัวเองคุณสามารถลอง:
file `which hostnameX 2>/dev/null` # just the file-command bad-usage error msg is printed
file `which hostnameX 2>/dev/null` 2>/dev/null # now nothing is printed on the screen :)
backtick `เรียกใช้เนื้อหาของสตริงที่ล้อมรอบดังนั้นบางสิ่งเช่นนี้
file `which hostname`
จะหาเส้นทางไปยังคำสั่ง hostname แล้วบอกวิธีสร้างมัน
คำสั่งที่คุณใส่ในคำถามของคุณid -u
จะได้รับรหัสผู้ใช้ที่มีประสิทธิภาพแล้วเปลี่ยนความเป็นเจ้าของ / somedir ให้กับผู้ใช้นั้น
สัญลักษณ์นี้หมายความว่าสิ่งใดก็ตามที่อยู่ภายในนั้นถูกตีความว่าเป็นผลของคำสั่งนั้น
ตัวอย่างเช่น:
$ls /home
one two
$pwd
/usr/three
$cp `pwd` /home
$ls /home
one two three
ผลลัพธ์ข้างต้นในthree
ไดเรกทอรีจะถูกคัดลอกไปยัง/home
ไดเรกทอรีของฉัน
backticks มีลักษณะคล้ายกับการทดแทนคำสั่ง นี้ backticks $()
ไวยากรณ์โบราณและรู้เครื่องหมายดอลลาร์กับสองวงเล็บเป็นเรื่องธรรมดา:
การทดแทนคำสั่งเป็นการดำเนินการเดียวที่มีไวยากรณ์เฉพาะเพื่อดำเนินการคำสั่งและเก็บเอาต์พุตไว้ในตัวแปรเพื่อใช้ในภายหลัง
thedate=$(date)
จากนั้นเราสามารถพิมพ์ผลลัพธ์: 'วันที่คือ% s \ n' "$ thedate" '
$()
ไวยากรณ์คำสั่งเปลี่ยนตัวเป็นdate
คำสั่งที่ตัวเองเป็น$(date)
ซึ่งมันจะเป็นการทดแทนprintf
ตามคำสั่งด้านบน
$(your expression)
เป็นวิธีที่ดีกว่าในการทำสิ่งเดียวกันกับที่$()
อนุญาตให้คุณสร้างการแสดงออก ตัวอย่างเช่น:cd $(dirname $(type -P touch))
จะนำคุณเข้าสู่ไดเรกทอรีที่มีtouch
คำสั่ง