ฉันจะใช้ตัวแปร Bash (สตริง) ที่มีเครื่องหมายคำพูดในคำสั่งได้อย่างไร


45

ตัวอย่างที่ล้มเหลวและเข้าใจง่าย:

FLAGS='--archive --exclude="foo bar.txt"'
rsync $FLAGS dir1 dir2

ฉันต้องใส่เครื่องหมายคำพูดราวกับว่าคำสั่งเป็นแบบนี้:

rsync --archive --exclude="foo bar.txt" dir1 dir2

คำตอบ:


54

คำตอบสั้น ๆ : ดูBashFAQ # 50 ("ฉันพยายามใส่คำสั่งในตัวแปร แต่กรณีที่ซับซ้อนล้มเหลวเสมอ!")

คำตอบที่ยาวนาน: การใส่คำสั่ง (หรือบางส่วนของคำสั่ง) ลงในตัวแปรแล้วนำกลับออกมาไม่เสียหาย เมื่อเชลล์ขยายตัวแปรบนบรรทัดคำสั่งหากตัวแปรอยู่ในเครื่องหมายคำพูดคู่จะไม่ได้ทำการแยกวิเคราะห์ ถ้ามันไม่ได้อยู่ในเครื่องหมายคำพูดช่องว่างในนั้นจะถูกแยกวิเคราะห์เป็นตัวแบ่งอาร์กิวเมนต์ แต่คำพูดและการหลบหนีจะไม่แยกวิเคราะห์ ไม่ว่าในกรณีใดการใส่เครื่องหมายคำพูดลงในค่าของตัวแปรนั้นไม่มีประโยชน์อะไรเลย

โดยปกติวิธีที่ดีที่สุดในการทำสิ่งนี้คือการใช้อาร์เรย์แทนตัวแปรข้อความธรรมดา:

FLAGS=(--archive --exclude="foo bar.txt")
rsync "${FLAGS[@]}" dir1 dir2

ศักดิ์สิทธิ์ Jezus มันใช้งานได้!
Slawomir


-2

ฉันไม่เห็นปัญหา:

$ FLAGS='--archive --exclude="foo bar.txt"'
$ echo $FLAGS
--archive --exclude="foo bar.txt"

บางทีคุณอาจต้องเสนอราคาอีกครั้ง:

$ rsync "$FLAGS" dir1 dir2

5
echoไม่แสดงสิ่งที่คุณคิด ลองprintargs() { printf "'%s' " "$@"; echo; }; printargs $FLAGS; printargs "$FLAGS"ดูว่าทำไมตัวเลือกเหล่านี้ไม่ทำงาน
Gordon Davisson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.