คำถามติดแท็ก command-substitution

คำถามเกี่ยวกับการทดแทนคำสั่งเชลล์ (เช่น $ (command) หรือ `command`) กลไกการทำงานไวยากรณ์ที่ถูกต้องและอื่น ๆ เพื่อไม่ให้สับสนกับ aliasing

6
อะไรคือความแตกต่างระหว่าง $ (สิ่งของ) และ `สิ่งของ '?
มีสองไวยากรณ์สำหรับการทดแทนคำสั่ง: ด้วยดอลลาร์วงเล็บและ backticks วิ่งtop -p $(pidof init)และtop -p `pidof init`ให้ผลลัพธ์เดียวกัน มีสองวิธีในการทำสิ่งเดียวกันหรือมีความแตกต่าง?

3
การอ้างอิงภายใน $ (การทดแทนคำสั่ง) ใน Bash
ในสภาพแวดล้อม Bash ของฉันฉันใช้ตัวแปรที่มีช่องว่างและฉันใช้ตัวแปรเหล่านี้ภายในการทดแทนคำสั่ง น่าเสียดายที่ฉันไม่พบคำตอบใน SE วิธีที่ถูกต้องในการอ้างอิงตัวแปรของฉันคืออะไร? และฉันควรทำอย่างไรถ้าสิ่งเหล่านี้ซ้อนอยู่? DIRNAME=$(dirname "$FILE") หรือฉันจะพูดนอกทดแทน? DIRNAME="$(dirname $FILE)" หรือทั้งคู่? DIRNAME="$(dirname "$FILE")" หรือฉันจะใช้เห็บกลับ? DIRNAME=`dirname "$FILE"` วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร? และฉันจะตรวจสอบได้อย่างง่ายดายว่าราคาถูกต้องหรือไม่

7
ส่งผ่านเอาต์พุตของคำสั่งก่อนหน้าไปยังอาร์กิวเมนต์
ฉันคำสั่งที่ส่งออกข้อมูลไปยัง stdout ( command1 -p=aaa -v=bbb -i=4) บรรทัดเอาต์พุตสามารถมีค่าต่อไปนี้: rate (10%) - name: value - 10Kbps ฉันต้องการ grep ผลลัพธ์นั้นเพื่อเก็บ 'rate' (ฉันเดาว่า pipe จะมีประโยชน์ที่นี่) และสุดท้ายฉันต้องการให้อัตรานั้นเป็นค่าของพารามิเตอร์ในคำสั่งที่สอง (สมมุติว่าcommand2 -t=${rate}) ดูเหมือนว่าจะเป็นเรื่องยุ่งยากในด้านของฉัน ฉันต้องการทราบวิธีการใช้ท่อ, grep, sed และอื่น ๆ ที่ดีกว่า ฉันได้ลองชุดค่าผสมจำนวนมากเช่นนั้นมาแล้ว แต่ฉันรู้สึกสับสนกับสิ่งเหล่านี้: $ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}

6
ฉันจะเรียกใช้งาน 'date' ภายในงาน cron tab ได้อย่างไร?
ฉันต้องการสร้างไฟล์บันทึกสำหรับสคริปต์ cron ที่มีชั่วโมงปัจจุบันในชื่อไฟล์บันทึก นี่คือคำสั่งที่ฉันพยายามใช้: 0 * * * * echo hello >> ~/cron-logs/hourly/test`date "+%d"`.log น่าเสียดายที่ฉันได้รับข้อความนี้เมื่อทำงาน: /bin/sh: -c: line 0: unexpected EOF while looking for matching ``' /bin/sh: -c: line 1: syntax error: unexpected end of file ฉันพยายามหนีdateส่วนต่างๆด้วยวิธีต่าง ๆ แต่ไม่มีโชคมาก เป็นไปได้ไหมที่จะทำให้สิ่งนี้เกิดขึ้นแบบอินไลน์ในไฟล์ crontab หรือฉันจำเป็นต้องสร้างเชลล์สคริปต์เพื่อทำสิ่งนี้?


3
การทำความเข้าใจ backtick (`)
ฉันลองคำสั่ง $ b=5; echo `$b`; -bash: 5: command not found แต่จะไม่พิมพ์ 5 อย่างที่ควรจะเป็น สิ่งที่ฉันหายไปที่นี่? `(backquote / backtick) หมายถึงอะไรในคำสั่ง? ดูเหมือนว่าจะ`ประเมินคำสั่งภายในและแทนที่พวกเขาด้วยการส่งออก

6
การทดแทนคำสั่ง: การแยกบรรทัดใหม่ แต่ไม่ใช่ที่ว่าง
ฉันรู้ว่าฉันสามารถแก้ปัญหานี้ได้หลายวิธี แต่ฉันสงสัยว่ามีวิธีที่จะทำโดยใช้เพียง bash ในตัวและถ้าไม่วิธีที่มีประสิทธิภาพที่สุดในการทำคืออะไร ฉันมีไฟล์ที่มีเนื้อหาเช่น AAA B C DDD FOO BAR โดยที่ฉันหมายความว่ามันมีหลายบรรทัดเท่านั้นและแต่ละบรรทัดอาจมีหรือไม่มีช่องว่างก็ได้ ฉันต้องการเรียกใช้คำสั่งเช่น cmd AAA "B C DDD" "FOO BAR" ถ้าฉันใช้cmd $(< file)ฉันจะได้รับ cmd AAA B C DDD FOO BAR และถ้าฉันใช้cmd "$(< file)"ฉันจะได้รับ cmd "AAA B C DDD FOO BAR" ฉันจะให้แต่ละบรรทัดปฏิบัติกับพารามิเตอร์หนึ่งตัวได้อย่างไร

5
ทำไมการแทนที่คำสั่งของเชลล์จึงฮุบไลน์อักขระบรรทัดใหม่?
ตามตัวอย่างต่อไปนี้และในคำถามล่าสุดของฉัน ในทุบตีอักขระขึ้นบรรทัดใหม่หายไปไหน ฉันต้องการรู้ว่า "ทำไม" มันเกิดขึ้น x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # Output is: 610a62 # The trailing newline from the 'echo' command # has been "deleted" by Command Substitution ฉันคิดว่าจะต้องมีเหตุผลที่สำคัญมากสำหรับการกระทำของเชลล์นั่นคือการแทนที่คำสั่งเพื่อลบข้อมูลบางส่วนออกจากผลลัพธ์ของคำสั่งมันเป็นการแทนที่ ... แต่ฉันไม่สามารถเอาหัวของฉันไปรอบ ๆ สิ่งนี้ได้ สิ่งที่ตรงกันข้ามที่ควรทำ .. คือ เพื่อส่งผ่านคำสั่งกลับไปยังกระบวนการสคริปต์ ... การถือตัวละครหนึ่งตัวกลับดูแปลกสำหรับฉัน แต่ฉันคิดว่ามันมีเหตุผลที่สมเหตุสมผลสำหรับมัน ... ฉันกระตือรือร้นที่จะค้นหาว่าเหตุผลนั้นคืออะไร .. .

4
ความแตกต่างระหว่าง `curl | sh` และ `sh -c“ $ (curl)””?
คำถามนี้ถูกโยกย้ายจาก Server Fault เนื่องจากสามารถตอบได้ใน Unix & Linux Stack Exchange อพยพ 2 ปีที่แล้ว วิธีการติดตั้งง่าย ๆ อย่างหนึ่งสำหรับ Docker (ตัวอย่าง) คือ: curl -sSL https://get.docker.com/ | sh อย่างไรก็ตามฉันได้เห็นบางอย่างที่มีลักษณะเช่นนี้ (โดยใช้ตัวอย่าง Docker): sh -c "$(curl -sSL https://get.docker.com/)" พวกมันดูเหมือนจะใช้งานได้เหมือนกัน แต่มีเหตุผลที่จะใช้อันหนึ่งกับอีกอันหนึ่งหรือไม่? หรือมันเป็นเพียงสิ่งที่ชอบ / ความงาม? (โปรดทราบว่าให้ระมัดระวังเมื่อเรียกใช้สคริปต์จากต้นกำเนิดที่ไม่รู้จัก)

1
ทำไมฟังก์ชั่นจะไม่กลับมาจนกว่ากระบวนการพื้นหลังจะสิ้นสุด
พิจารณาสคริปต์นี้: #!/bin/bash function start { leafpad & echo $! } PID=$(start) echo "PID is $PID" สคริปต์ไม่ดำเนินการผ่านวงเล็บปีกกาปิดจนกว่ากระบวนการ leafpad จะสิ้นสุดลงแม้ว่าจะเป็นกระบวนการพื้นหลัง ทำไมนี้ เป็นไปได้หรือไม่ที่จะเริ่มกระบวนการพื้นหลังจากฟังก์ชั่น?

1
POSIX ต้องการอะไรสำหรับเอกสารที่ยกมาที่นี่ภายในการทดแทนคำสั่ง?
ในคำถามนี้มีคนรายงานปัญหาการใช้ที่นี่เอกสารด้วยคำคั่นอ้างภายใน$(...)แทนคำสั่งที่เครื่องหมาย\ที่ท้ายบรรทัดภายในการเรียกเอกสารการขึ้นบรรทัดใหม่เข้าสู่เส้นต่อเนื่องขณะเดียวกันที่นี่เอกสารนอกงานคำสั่งเปลี่ยนตัวตามที่คาดไว้ . นี่คือตัวอย่างเอกสารที่ง่ายขึ้น: cat <<'EOT' abc ` def ghi \ jkl EOT ซึ่งรวมถึง backtick หนึ่งรายการและแบ็กสแลชหนึ่งรายการที่ท้ายบรรทัด ตัวคั่นถูกยกมาดังนั้นจึงไม่มีการขยายเกิดขึ้นภายในร่างกาย ใน Bourne-alikes ทั้งหมดฉันสามารถค้นหาผลลัพธ์นี้เป็นคำต่อคำเนื้อหา หากฉันวางเอกสารเดียวกันไว้ภายในการทดแทนคำสั่งดังนี้: x=$(cat <<'EOT' abc ` def ghi \ jkl EOT ) echo "$x" จากนั้นพวกเขาจะไม่ทำงานเหมือนกันอีกต่อไป: dash, ash, zsh, ksh93, BusyBox ash, mkshและ SunOS 5.10 POSIX shทั้งหมดให้เนื้อหาคำต่อคำของเอกสารเป็นมาก่อน Bash 3.2 ให้ข้อผิดพลาดทางไวยากรณ์สำหรับ backtick ที่ไม่ตรงกัน ด้วย …

2
คำพูดซ้อนคู่ในหนึ่งคะแนนโหวตสูง
คำตอบ StackOverflow ด้วย> 3.5K โหวตให้คุณสมบัติหนึ่งซับสำหรับการกำหนดไปDIRยังไดเรกทอรีของสคริปต์ทุบตีปัจจุบัน: DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ฉันงงกับคำพูดซ้อนคู่ เท่าที่ฉันสามารถบอกได้ชิ้นส่วนต่อไปนี้เป็นเครื่องหมายคำพูดคู่: "$( cd " "${BASH_SOURCE[0]}" " && pwd )" ... และทุกอย่างอื่นทางด้านขวาของ=(เช่น$( dirnameและ)) ไม่มีการอ้างอิง ในคำอื่น ๆ ฉันคิดว่าตัวละครที่ 2, 4 และ 6 ""ปิด" ตัวที่ 1, 3 และ 5 "ตามลำดับ ฉันเข้าใจว่าการเสนอราคาสองเท่าในการ"${BASH_SOURCE[0]}"บรรลุผลสำเร็จ แต่อะไรคือจุดประสงค์ของการเสนอราคาสองคู่อื่น ๆ หากในอีกทางหนึ่ง (และคะแนนโหวตสูงถึงแม้จะมี) ตัวอย่างข้างต้นไม่ถูกต้องสิ่งที่เป็นวิธีที่เหมาะสมเพื่อให้บรรลุเจตนาที่ระบุ? (โดยเจตนาที่ระบุฉันหมายถึง: รวบรวมค่าที่ส่งคืนโดยpwdหลังจากการcdเข้าสู่ไดเรกทอรีที่ส่งคืนโดยครั้งแรกdirname …


3
เหตุผลใดที่จะใช้หรือสอนการทดแทน '…' เพื่อการพัฒนาใหม่?
มันเป็นความเข้าใจของฉันว่า$(...)ไวยากรณ์แทนคำสั่งที่ทันสมัยกว่าเป็นที่ต้องการมากกว่า`ไวยากรณ์แบบเก่าเนื่องจากง่ายต่อการทำรังและหลบหนีจากข้อผิดพลาด นอกจากนี้ดูเหมือนว่า/bin/shกระสุนสไตล์ส่วนใหญ่ในการสนับสนุนการใช้งานที่ทันสมัย$(…): ทุบตี เถ้า (และดังนั้น BusyBox, Linux ส่วนใหญ่ที่ฝังตัว) ชน FreeBSD / bin / sh และ$(…)ถูกระบุโดย IEEE 1003.1 ดังนั้นฉันมี 2 คำถามที่เกี่ยวข้องมาก: มีเหตุผลใดบ้างที่จะใช้ `ในการพัฒนาเชลล์สคริปต์ใหม่เว้นแต่คุณจะรู้ถึงระบบเก่าที่สคริปต์จะต้องทำงาน มีเหตุผลใดที่จะไม่สอนนักเรียนโปรแกรม UNIX เพียงเพื่อเขียน$(...)และอภิปราย`เฉพาะในรูปแบบที่ล้าสมัยที่พวกเขาจะพบถ้าพวกเขากำลังอ่านเชลล์สคริปต์ของผู้พัฒนาคนอื่น (และอาจจำเป็นถ้าพวกเขากำลังทำงานกับระบบเก่าหรือไม่เป็นมาตรฐาน ด้วยเหตุผลบางอย่าง)?

5
การใช้รายการชื่อไฟล์ที่สร้างขึ้นเป็นรายการอาร์กิวเมนต์ - พร้อมช่องว่าง
findฉันพยายามที่จะเรียกใช้สคริปต์กับรายการของชื่อไฟล์ที่เก็บรวบรวมโดย ไม่มีอะไรพิเศษเพียง someting เช่นนี้: $ myscript `find . -name something.txt` ปัญหาคือชื่อพา ธ บางส่วนมีช่องว่างดังนั้นพวกเขาจึงแยกออกเป็นชื่อที่ไม่ถูกต้องสองชื่อในการขยายอาร์กิวเมนต์ ปกติฉันจะล้อมรอบชื่อด้วยเครื่องหมายคำพูด แต่ที่นี่พวกเขาแทรกโดยการขยาย backquote ฉันพยายามกรองเอาท์พุทของfindและรอบ ๆ ชื่อไฟล์แต่ละรายการด้วยเครื่องหมายคำพูด แต่เมื่อถึงเวลาที่เห็นพวกเขามันสายเกินไปที่จะดึงออกมาและพวกเขาจะถือว่าเป็นส่วนหนึ่งของชื่อไฟล์: $ myscript `find . -name something.txt | sed 's/.*/"&"/'` No such file or directory: '"./somedir/something.txt"' ใช่นั่นเป็นกฎสำหรับวิธีการประมวลผลบรรทัดคำสั่ง แต่ฉันจะแก้ไขได้อย่างไร นี่เป็นเรื่องที่น่าอาย แต่ฉันไม่สามารถหาวิธีที่เหมาะสมได้ ในที่สุดฉันก็รู้ว่าจะทำอย่างไรกับxargs -0 -n 10000... แต่มันเป็นแฮ็คที่น่าเกลียดที่ฉันยังต้องการถาม: ฉันจะอ้างถึงผลลัพธ์ของการขยาย backquote หรือบรรลุผลแบบเดียวกันได้อย่างไร? แก้ไข:ฉันสับสนเกี่ยวกับความจริงที่ว่าxargs ไม่เก็บขัดแย้งทั้งหมดเป็นรายการอาร์กิวเมนต์เดียวเว้นแต่จะบอกเป็นอย่างอื่นหรือข้อ จำกัด …

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