สมมติว่าฉันมีสคริปต์เปลือกทุบตีเรียกMyscript.sh
ว่าต้องการอาร์กิวเมนต์หนึ่งตัวเป็นอินพุต
แต่ฉันต้องการเนื้อหาของไฟล์ข้อความที่เรียกว่าtext.txt
เป็นอาร์กิวเมนต์
ฉันได้ลองแล้ว แต่มันไม่ทำงาน:
cat text.txt | ./Myscript.sh
มีวิธีทำเช่นนี้หรือไม่?
สมมติว่าฉันมีสคริปต์เปลือกทุบตีเรียกMyscript.sh
ว่าต้องการอาร์กิวเมนต์หนึ่งตัวเป็นอินพุต
แต่ฉันต้องการเนื้อหาของไฟล์ข้อความที่เรียกว่าtext.txt
เป็นอาร์กิวเมนต์
ฉันได้ลองแล้ว แต่มันไม่ทำงาน:
cat text.txt | ./Myscript.sh
มีวิธีทำเช่นนี้หรือไม่?
คำตอบ:
คุณสามารถใช้ไพพ์เอาต์พุตเป็นอาร์กิวเมนต์เชลล์สคริปต์
ลองวิธีนี้:
cat text.txt | xargs -I {} ./Myscript.sh {}
ลอง,
$ cat comli.txt
date
who
screen
wget
$ cat comli.sh
#!/bin/bash
which $1
$ for i in `cat comli.txt` ; do ./comli.sh $i ; done
เพื่อให้คุณสามารถป้อนค่าหนึ่งโดยหนึ่งจากcomli.sh
comli.txt
การทดแทนกระบวนการ
./Myscript.sh <(cat text.txt)
ดูเช่นhttps://www.gnu.org/software/bash/manual/bash.html#Process-Substitution
โดยการอ่าน stdin ด้วย mapfile คุณสามารถตั้งค่าพารามิเตอร์ตำแหน่งอีกครั้ง
#!/bin/bash
[[ -p /dev/stdin ]] && { mapfile -t; set -- "${MAPFILE[@]}"; }
for i in $@; do
echo "$((++n)) $i"
done
(การอ้างถึง "$ @" จะสร้างfor
บรรทัดวนรอบแทน)
$ cat test.txt | ./script.sh
1 one
2 two
3 tree
เพื่อให้ @ bac0n สมบูรณ์ซึ่ง IMHO เป็นคำตอบเดียวที่ถูกต้องนี่คือ short-liner ที่จะเพิ่มข้อโต้แย้งไปป์ไลน์ในรายการอาร์กิวเมนต์ของสคริปต์ของคุณ:
#!/bin/bash
args=$@
[[ -p /dev/stdin ]] && { mapfile -t; set -- "${MAPFILE[@]}"; set -- $@ $args; }
echo $@
ตัวอย่างการใช้:
$ ./script.sh arg1 arg2 arg3
> arg1 arg2 arg3
$ echo "piped1 piped2 piped3" | ./script.sh
> piped1 piped2 piped3
$ echo "piped1 piped2 piped3" | ./script.sh arg1 arg2 arg3
> piped1 piped2 piped3 arg1 arg2 arg3