`(backquote / backtick) หมายถึงอะไรในคำสั่ง?


159

ฉันเจอคำสั่งต่อไปนี้:

sudo chown `id -u` /somedir

และฉันสงสัยว่า: ความหมายของ`สัญลักษณ์คืออะไร ฉันสังเกตเห็นว่าขณะที่คำสั่งข้างต้นทำงานได้ดีคำสั่งด้านล่างไม่ทำงาน:

sudo chown 'id -u' /somedir

คำตอบ:


199

นี่คือ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 อย่างแท้จริงเช่นในสตริงคุณสามารถหลบหนีได้โดยการวางแบ็กสแลช ( \) ไว้ข้างหน้า


36
วิธีนี้อธิบายการแบ็คทีที่ค่อนข้างดี แต่การใช้$(your expression)เป็นวิธีที่ดีกว่าในการทำสิ่งเดียวกันกับที่$()อนุญาตให้คุณสร้างการแสดงออก ตัวอย่างเช่น: cd $(dirname $(type -P touch))จะนำคุณเข้าสู่ไดเรกทอรีที่มีtouchคำสั่ง
Khaja Minhajuddin

11
@KhajaMinhajuddin คุณถูกต้องแน่นอนเกี่ยวกับการทำรัง - คำถามที่กล่าวถึงข้างต้นครอบคลุมถึงรายละเอียด แต่ถึงแม้ผมคิดว่ามันเป็นวิธีที่ดีที่จะใช้$()ในสถานการณ์ส่วนใหญ่ก็ไม่ได้ทำให้ backticks เลวร้ายยิ่งสิ่งที่ เพื่อวัตถุประสงค์ในทางปฏิบัติเราต้องยอมรับว่าพวกมันเร็วกว่ามากในการพิมพ์บนบรรทัดคำสั่ง (2 การกดแป้นพิมพ์เมื่อเทียบกับอย่างน้อย 5 รวมถึงShift)
rozcietrzewiacz

2
@rozcietrzewiacz คำพูดสุดท้ายของคุณอาจเป็นจริงสำหรับคีย์บอร์ดส่วนใหญ่ แต่$( )แน่นอนว่าจะพิมพ์ได้ง่ายกว่า` `คีย์บอร์ดภาษาฝรั่งเศสอย่างน้อย
jlliagre

1
@KhajaMinhajuddin คุณสามารถซ้อน backticks ได้ แต่คุณต้องหลบออกจาก backticks ระดับที่ 2 และการทำรังในระดับที่ 2 คุณต้องใช้ 3 backticks ระดับ 3 ทำรัง 5 backticks ระดับ 4 7 และ c
Justin CB

66

ฉันต้องการเพิ่มคะแนนอีกเล็กน้อยที่นี่

backtick `…`เรียกว่าจริงคำสั่งเปลี่ยนตัว วัตถุประสงค์ของการทดแทนคำสั่งคือการประเมินคำสั่งที่อยู่ภายใน backtick และให้ผลลัพธ์เป็นอาร์กิวเมนต์สำหรับคำสั่งจริง

ทดแทนคำสั่งที่สามารถทำได้ในสองวิธีหนึ่งคือการใช้$(…)และอื่น ๆ `…`คือ ทั้งสองทำงานเหมือนกัน แต่$(…)รูปแบบเป็นวิธีที่ทันสมัยและมีความชัดเจนและอ่านง่ายขึ้น

และอื่น ๆ

sudo chown $(id -u) /somedir

สามารถเป็นที่ต้องการมากกว่าที่อื่น ๆ

และอีกหนึ่งสิ่งที่คุณจำเป็นต้องทราบที่นี่เป็นคำสั่งเปลี่ยนตัวความสัมพันธ์กับทุบตีอ้างกฎระเบียบดังกล่าวในทุบตีเอกสาร

หากการแทนที่ปรากฏภายในเครื่องหมายคำพูดคู่การแยกคำและการขยายชื่อไฟล์จะไม่ถูกดำเนินการกับผลลัพธ์


8
นอกจากนี้ยัง$(...)ดีกว่ารัง
Kusalananda

$()และ"``"ไม่ทำงานในลักษณะเดียวกัน
Kun

10

หนึ่งบันทึกของการชี้แจงที่ไม่ค่อยครอบคลุม:

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 :)

4

backtick `เรียกใช้เนื้อหาของสตริงที่ล้อมรอบดังนั้นบางสิ่งเช่นนี้

file `which hostname`

จะหาเส้นทางไปยังคำสั่ง hostname แล้วบอกวิธีสร้างมัน

คำสั่งที่คุณใส่ในคำถามของคุณid -uจะได้รับรหัสผู้ใช้ที่มีประสิทธิภาพแล้วเปลี่ยนความเป็นเจ้าของ / somedir ให้กับผู้ใช้นั้น


2

สัญลักษณ์นี้หมายความว่าสิ่งใดก็ตามที่อยู่ภายในนั้นถูกตีความว่าเป็นผลของคำสั่งนั้น

ตัวอย่างเช่น:

$ls /home
one two
$pwd
/usr/three
$cp `pwd` /home
$ls /home
one two three

ผลลัพธ์ข้างต้นในthreeไดเรกทอรีจะถูกคัดลอกไปยัง/homeไดเรกทอรีของฉัน


1

backticks มีลักษณะคล้ายกับการทดแทนคำสั่ง นี้ backticks $()ไวยากรณ์โบราณและรู้เครื่องหมายดอลลาร์กับสองวงเล็บเป็นเรื่องธรรมดา:

การทดแทนคำสั่งคืออะไร?

การทดแทนคำสั่งเป็นการดำเนินการเดียวที่มีไวยากรณ์เฉพาะเพื่อดำเนินการคำสั่งและเก็บเอาต์พุตไว้ในตัวแปรเพื่อใช้ในภายหลัง

ตัวอย่างที่มีวันที่:

thedate=$(date)

จากนั้นเราสามารถพิมพ์ผลลัพธ์: 'วันที่คือ% s \ n' "$ thedate" '

  1. $()ไวยากรณ์คำสั่งเปลี่ยนตัวเป็น
  2. dateคำสั่งที่ตัวเองเป็น
  3. รวมทั้งสองอย่างเข้าด้วยกัน$(date)ซึ่งมันจะเป็นการทดแทน
  4. เราแสดงค่าเอาต์พุตที่เก็บไว้โดยตัวแปรด้วยprintfตามคำสั่งด้านบน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.