วิธีทำรัง Bash backticks อย่างถูกต้อง


95

ไม่ว่าฉันจะพลาดฟันเฟืองหรือแบ็กแลชบางอย่างก็ดูเหมือนจะไม่ได้ผลกับการวนซ้ำของโปรแกรมเมอร์ - ใบเสนอราคามากเกินไป

$ echo "hello1-`echo hello2-\`echo hello3-\`echo hello4\`\``"

hello1-hello2-hello3-echo hello4

ต้องการ

hello1-hello2-hello3-hello4-hello5-hello6-...

คำถามควรอ่าน "วิธีใช้ Bash backticks ซ้ำ" สิ่งนี้น่าจะช่วยชาว Google ได้
Joey Adams

คุณพยายามจะทำอะไร.? สิ่งนี้ไม่มีความหมายเลย
ghostdog74

1
@joey เปลี่ยนชื่อแล้ว ure welcome: D
Stormenet

1
อ๊ะเกานั่น ควรอ่าน "ฉันจะทำรังแบ็กติกในทุบตีได้อย่างไร" . ฉันมีการเรียกซ้ำและการทำรังปะปนกัน
Joey Adams

backticks กำลังจึงใช้deprecated $(cmd)
Timo

คำตอบ:


149

ใช้$(commands)แทน:

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4

$(commands) ทำเช่นเดียวกับแบ็กติก แต่คุณสามารถทำรังได้

คุณอาจสนใจการขยายช่วง Bash:

echo hello{1..10}
hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10

+1 เหมือน {1..10} จำกัด ด้วยอาร์เรย์? ZSH สามารถ "$ {$ (date) [2,4]}" ทำไมไม่: "echo $ {echo hello1 - $ (echo hello2) [1]}"?
hhh

35

หากคุณยืนยันที่จะใช้ backticks สามารถทำได้ดังต่อไปนี้

$ echo "hello1-`echo hello2-\`echo hello3-\\\`echo hello4\\\`\``"

คุณต้องใส่แบ็กสแลชที\\ \\\\ \\\\\\\\ละ 2x $(commands)ไปเรื่อย ๆมันน่าเกลียดมากใช้ตามคำแนะนำอื่น ๆ


11

ทุกครั้งที่คุณต้องการประเมินคำสั่งให้ใช้command substitution:

$(command)

เมื่อใดก็ตามที่คุณต้องการประเมินนิพจน์เลขคณิตให้ใช้expression substitution:

$((expr))

คุณสามารถซ้อนสิ่งเหล่านี้ได้ดังนี้:

สมมติว่า file1.txt ยาว 30 บรรทัดและ file2.txt ยาว 10 บรรทัดเกินกว่าที่คุณจะประเมินนิพจน์ได้ดังนี้

$(( $(wc -l file1.txt) - $(wc -l file2.txt) ))

ซึ่งจะส่งออก 20 (ความแตกต่างของจำนวนบรรทัดระหว่างสองไฟล์)


10

ง่ายกว่ามากถ้าคุณใช้$(cmd) ไวยากรณ์การแทนที่คำสั่งของ bash ซึ่งเป็นมิตรกับการซ้อนกันมากขึ้น:

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4

5
นี้ไม่ได้ จำกัดทุบตี มีอยู่ในเชลล์ทั้งหมดที่เป็นไปตาม POSIX 1003.1 (“ เชลล์ POSIX”) และเชลล์ที่ได้รับบอร์นส่วนใหญ่ ( ksh , ash , dash , bash , zshฯลฯ ) แม้ว่าจะไม่ใช่ Bourne เชลล์ที่แท้จริง (เช่นมรดกตกทอด /sh.html )
Chris Johnsen

ว้าวการประทับเวลาของคำตอบนี้เป็นสิ่งที่บ่งบอกถึงคำตอบใน @joey_adams! ความซิงโครไนซ์ในความหมายที่แท้จริงที่สุด :) การโหวตที่นี่ด้วย (:
drevicko

0

บางครั้งการทำรังแบบแบ็คทิกสามารถใช้แทนxargsและท่อได้

$ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1
hello1 hello2 hello3 hello4

ข้อเสียเปรียบของวิธีนี้คือ:

  • ต้องระบุอาร์กิวเมนต์ทั้งหมดในลำดับย้อนกลับ (4 → 1);
  • อาร์กิวเมนต์ทั้งหมดกลายเป็นช่องว่างคั่น (แก้ไขได้ด้วยtr):

    $ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1 | tr ' ' '-'
    hello1-hello2-hello3-hello4
    


ลองแสดงกรณีการใช้งานจริง

คำสั่งต่อไปนี้ทำงานใน bash แต่ไม่ใช่ใน tcsh (การทำรัง backtick ไม่ได้รับการจัดการที่ดีใน tcsh)

$ ls $(dirname $(which bash))
$ ls `dirname \`which bash\``

สามารถทดแทนได้ด้วย

$ which bash | xargs dirname | xargs ls
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.