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

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

7
เหตุใดจึงมีความแตกต่างในเวลาดำเนินการของเสียงก้องและแมว?
การตอบคำถามนี้ทำให้ฉันถามคำถามอื่น: ฉันคิดว่าสคริปต์ต่อไปนี้ทำสิ่งเดียวกันและอันที่สองควรเร็วกว่ามากเพราะการใช้ครั้งแรกcatที่ต้องการเปิดไฟล์ซ้ำไปซ้ำมา แต่อย่างที่สองเปิดไฟล์เท่านั้น เพียงครั้งเดียวและเพียงแค่ก้องตัวแปร: (ดูหัวข้อการปรับปรุงสำหรับรหัสที่ถูกต้อง) ครั้งแรก: #!/bin/sh for j in seq 10; do cat input done >> output ประการที่สอง: #!/bin/sh i=`cat input` for j in seq 10; do echo $i done >> output ในขณะที่อินพุตประมาณ 50 เมกะไบต์ แต่เมื่อฉันลองครั้งที่สองมันก็ช้าเกินไปเพราะการสะท้อนตัวแปรiเป็นกระบวนการที่ยิ่งใหญ่ ฉันยังมีปัญหากับสคริปต์ที่สองเช่นขนาดของไฟล์ที่ส่งออกต่ำกว่าที่คาดไว้ ฉันยังตรวจสอบหน้า man ของechoและcatเปรียบเทียบ: echo - แสดงบรรทัดข้อความ cat - เชื่อมไฟล์และพิมพ์บนเอาต์พุตมาตรฐาน แต่ฉันไม่ได้รับความแตกต่าง ดังนั้น: ทำไมแมวถึงเร็วขนาดนี้และเสียงก้องช้าในบทที่สอง? …

2
อักขระขึ้นบรรทัดใหม่ที่หายไปจากการทดแทนคำสั่งของฉันอยู่ที่ไหน
รหัสต่อไปนี้อธิบายสถานการณ์ได้ดีที่สุด เหตุใดบรรทัดสุดท้ายจึงไม่แสดงเอาต์พุตอักขระขึ้นบรรทัดใหม่ เอาต์พุตของแต่ละบรรทัดจะแสดงในความคิดเห็น ฉันใช้GNU bash เวอร์ชัน 4.1.5 echo -n $'a\nb\n' | xxd -p # 610a620a x=$'a\nb\n' ; echo -n "$x" | xxd -p # 610a620a echo -ne "a\nb\n" | xxd -p # 610a620a x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # 610a62

3
ข้อผิดพลาดในการดักจับในการทดแทนคำสั่งโดยใช้“ -o errtrace” (เช่น set -E)
ตามคู่มืออ้างอิงนี้: -E (เช่น -o errtrace) หากตั้งค่ากับดักใด ๆ บน ERR จะได้รับมรดกโดยฟังก์ชั่นของเชลล์การแทนที่คำสั่งและคำสั่งที่ดำเนินการในสภาพแวดล้อม subshell กับดัก ERR โดยปกติจะไม่สืบทอดในกรณีเช่นนี้ อย่างไรก็ตามฉันต้องตีความอย่างผิด ๆ เพราะสิ่งต่อไปนี้ใช้ไม่ได้: #!/usr/bin/env bash # -*- bash -*- set -e -o pipefail -o errtrace -o functrace function boom { echo "err status: $?" exit $? } trap boom ERR echo $( made up name ) …

5
ไฟล์ grep จากรายการ
ฉันกำลังพยายามเรียกใช้ grep กับรายการของไฟล์สองสามร้อย: $ head -n 3 <(cat files.txt) admin.php ajax/accept.php ajax/add_note.php อย่างไรก็ตามแม้ว่าฉันกำลังค้นหาสตริงที่ฉันรู้ว่าพบในไฟล์ต่อไปนี้จะไม่ค้นหาไฟล์: $ grep -i 'foo' <(cat files.txt) $ grep -i 'foo' admin.php The foo was found ฉันคุ้นเคยกับการ-fตั้งค่าสถานะซึ่งจะอ่านรูปแบบจากไฟล์ แต่จะอ่านไฟล์อินพุตได้อย่างไร? ฉันได้พิจารณาวิธีแก้ปัญหาที่น่ากลัวของการคัดลอกไฟล์ไปยังไดเรกทอรีชั่วคราวตามที่cpดูเหมือนว่าจะสนับสนุน<(cat files.txt)รูปแบบและจากนั้นมีการ grepping ไฟล์ เชอร์ลี่ย์มีวิธีที่ดีกว่า

2
คำพูดซ้อนใน subshells
ว่าฉันต้องใช้อัญประกาศเพื่อสรุปผลลัพธ์ subshell เช่น: DATA="$(cat file.hex | xxd -r)" แต่ฉันต้องทำรังสิ่งเช่นนี้: DATA="$(cat file.hex | xxd -r | tr -d \"$(cat trim.txt)\")" ฉันไม่สามารถใช้เครื่องหมายคำพูดเดี่ยวได้เพราะสิ่งเหล่านั้นไม่ได้ขยายตัวแปรที่อยู่ข้างใน การหลีกเลี่ยงการพูดไม่ทำงานเพราะมันเป็นเสมือนข้อความแฝง ฉันจะจัดการสิ่งนี้ได้อย่างไร

1
ksh93 หลีกเลี่ยงการส้อมในการทดแทนคำสั่งได้อย่างไร
ป.ร. ให้ไว้ cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))' หอยมีแนวโน้มที่จะต้องทำให้ 2 ส้อมเพื่อให้มันเกิดขึ้น strace-f(){ strace -f "$@" 2>&1; }; for sh in dash bash zsh ksh; do printf "$sh\t" ; strace-f $sh -c "$cmd" |grep -e clone -e fork -c; done ยกเว้นkshอย่างกล้าหาญทำให้มันไม่ได้ฟอร์กครั้งเดียว: dash 2 bash 2 zsh 2 ksh 0 …

3
หลายตัวแปรสำหรับลูป
มีวิธีการระบุตัวแปรหลายตัว (ไม่ใช่แค่จำนวนเต็ม) ในการforวนซ้ำbashหรือไม่? ฉันอาจมี 2 ไฟล์ที่มีข้อความใด ๆ ที่ฉันต้องทำงานด้วย สิ่งที่ฉันต้องการตามหน้าที่คืออะไร: for i in $(cat file1) and j in $(cat file2); do command $i $j; done ความคิดใด ๆ

3
ฉันจะสร้างข้อโต้แย้งไปยังคำสั่งอื่นผ่านการทดแทนคำสั่งได้อย่างไร
ติดตามจาก: พฤติกรรมที่ไม่คาดคิดในการทดแทนคำสั่งเชลล์ ฉันมีคำสั่งที่สามารถใช้รายการของการขัดแย้งขนาดใหญ่ซึ่งบางอย่างสามารถมีช่องว่างที่ถูกต้องตามกฎหมาย (และอาจเป็นอย่างอื่น) ฉันเขียนสคริปต์ที่สามารถสร้างข้อโต้แย้งเหล่านั้นสำหรับฉันด้วยเครื่องหมายคำพูด แต่ฉันต้องคัดลอกและวางผลลัพธ์เช่น ./somecommand <output on stdout with quoting> ./othercommand some_args <output from above> ฉันพยายามทำให้เพรียวบางนี้โดยทำ ./othercommand $(./somecommand) และพบพฤติกรรมที่ไม่คาดคิดตามที่กล่าวถึงข้างต้น คำถามคือ - สามารถใช้การทดแทนคำสั่งได้อย่างน่าเชื่อถือในการสร้างอาร์กิวเมนต์เพื่อothercommandให้ข้อโต้แย้งบางอย่างจำเป็นต้องมีการเสนอราคาและสิ่งนี้ไม่สามารถเปลี่ยนแปลงได้?

4
ทำความเข้าใจกับการทดแทนคำสั่ง Read-a-File ของ Bash
ฉันพยายามเข้าใจว่า Bash ปฏิบัติต่อบรรทัดต่อไปนี้อย่างไร: $(< "$FILE") ตามหน้า Bash man นี่เทียบเท่ากับ: $(cat "$FILE") และฉันสามารถทำตามบรรทัดของการให้เหตุผลสำหรับบรรทัดที่สองนี้ Bash ดำเนินการขยายตัวตัวแปร$FILEเข้าสู่การทดแทนคำสั่งส่งค่า$FILEถึงcatcat ส่งออกเนื้อหาของ$FILEไปยังเอาต์พุตมาตรฐานการแทนที่คำสั่งเสร็จสิ้นโดยแทนที่ทั้งบรรทัดด้วยเอาต์พุตมาตรฐานที่เป็นผลมาจากคำสั่งด้านในและ Bash พยายามดำเนินการเช่นนั้น คำสั่งง่ายๆ อย่างไรก็ตามสำหรับบรรทัดแรกที่ฉันกล่าวถึงข้างต้นฉันเข้าใจว่า: Bash ทำการแทนที่ตัวแปรใน$FILEBash เปิด$FILEสำหรับการอ่านในอินพุตมาตรฐานอินพุตมาตรฐานจะถูกคัดลอกไปยังเอาต์พุตมาตรฐานการทดแทนคำสั่งเสร็จสิ้นและ Bash พยายามเรียกใช้มาตรฐานที่เป็นผลลัพธ์ เอาท์พุต ใครช่วยอธิบายให้ฉันฟังได้ว่าเนื้อหาของการเปลี่ยน$FILEจาก stdin เป็น stdout ได้อย่างไร?

2
การมอบหมายเป็นเหมือนคำสั่งที่มีสถานะการออกยกเว้นเมื่อมีการทดแทนคำสั่ง?
ดูตัวอย่างต่อไปนี้และผลลัพธ์ใน POSIX เชลล์: false;echo $?หรือfalse || echo 1:1 false;foo="bar";echo $?หรือfoo="bar" && echo 0:0 foo=$(false);echo $?หรือfoo=$(false) || echo 1:1 foo=$(true);echo $?หรือfoo=$(true) && echo 0:0 ตามที่ระบุไว้โดยคำตอบที่ได้รับการโหวตสูงสุดที่/programming/6834487/what-is-the-variable-in-shell-scripting : $? ถูกใช้เพื่อค้นหาค่าส่งคืนของคำสั่งที่เรียกใช้งานครั้งสุดท้าย นี่อาจเป็นความเข้าใจผิดเล็กน้อยในกรณีนี้ดังนั้นขอนิยาม POSIX ซึ่งอ้างถึงในโพสต์จากกระทู้นั้น: ? ขยายเป็นสถานะทางออกทศนิยมของไปป์ไลน์ล่าสุด (ดูที่ Pipelines) ดังนั้นดูเหมือนว่าการมอบหมายตัวเองนับเป็นคำสั่ง (หรือมากกว่าส่วนท่อ) ที่มีค่าศูนย์ทางออก แต่จะใช้ก่อนที่ด้านขวาของการมอบหมาย (เช่นการทดแทนคำสั่งเรียกในตัวอย่างของฉันที่นี่) ฉันเห็นว่าพฤติกรรมนี้เหมาะสมจากมุมมองเชิงปฏิบัติ แต่ดูเหมือนว่าฉันค่อนข้างผิดปกติที่งานมอบหมายจะนับตามลำดับนั้น อาจจะชัดเจนมากกว่านี้ทำไมมันแปลกสำหรับฉันลองสมมติว่าการบ้านเป็นหน้าที่: ASSIGNMENT( VARIABLE, VALUE ) แล้วfoo="bar"จะเป็น ASSIGNMENT( "foo", "bar" …

2
สถานะการส่งคืนของการกำหนดตัวแปรกำหนดอย่างไร?
ฉันได้เห็นโครงสร้างในสคริปต์เช่นนี้ if somevar="$(somecommand 2>/dev/null)"; then ... fi เอกสารนี้อยู่ที่ไหนสักแห่ง? สถานะการส่งคืนของตัวแปรถูกกำหนดอย่างไรและเกี่ยวข้องกับการทดแทนคำสั่งอย่างไร (ตัวอย่างเช่นฉันจะได้ผลลัพธ์เดียวกันด้วยif echo "$(somecommand 2>/dev/null)"; then)

3
การแทนที่คำสั่งสามารถซ้อนในการแทนที่ตัวแปรได้หรือไม่?
ฉันต้องการใช้การทดแทนตัวแปรบนสตริงเฉพาะที่ฉันเข้าถึงผ่านคำสั่ง ตัวอย่างเช่นหากฉันคัดลอกบางสิ่งลงในคลิปบอร์ดของฉันฉันสามารถเข้าถึงได้เช่นนี้ $ xclip -o -selection clipboard Here's a string I just copied. หากฉันกำหนดให้กับตัวแปรดังนั้นฉันสามารถทำการทดแทนตัวแปรได้ $ var=$(xclip -o -selection clipboard) $ echo $var Here's a string I just copied. $ echo ${var/copi/knott} Here's a string I just knotted. อย่างไรก็ตามมีวิธีการเปลี่ยนตัวแปรโดยไม่ต้องกำหนดให้กับตัวแปรหรือไม่? แนวคิดบางอย่างเช่นนี้ $ echo ${$(xclip -o -selection clipboard)/copi/knott} bash: ${$(xclip -o -selection clipboard)/copi/knott}: …

1
ทำไมไม่มีบรรทัดใหม่ในตอนท้ายของการอ้างถึง subshell และส่งผ่านผลลัพธ์เพื่อ echo
เมื่อฉันทำls | grep pngผลลัพธ์ของ grep คือ: 2015-05-15-200203_1920x1080_scrot.png 2015-05-16-025536_1920x1080_scrot.png (ชื่อไฟล์ขึ้นบรรทัดใหม่ชื่อไฟล์ขึ้นบรรทัดใหม่) ดังนั้นecho $(ls | grep png)ผลลัพธ์: 2015-05-15-200203_1920x1080_scrot.png 2015-05-16-025536_1920x1080_scrot.png (ชื่อไฟล์, ช่องว่างจากการแยกคำ, ชื่อไฟล์, บรรทัดใหม่ !! จาก echo !!) นั่นคือทั้งหมดที่ตกลง แต่เมื่อฉันทำเช่นนี้เพื่อป้องกันการแยกคำ: echo "$(ls | grep png)"ออกเป็น: 2015-05-15-200203_1920x1080_scrot.png 2015-05-16-025536_1920x1080_scrot.png และคำถามของฉันคือขึ้นบรรทัดใหม่ที่สอง (หนึ่งควรมาจาก grep และหนึ่งจาก echo)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.