การขยายพารามิเตอร์
คำตอบที่ชัดเจนคือใช้รูปแบบพิเศษของการขยายพารามิเตอร์:
: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}
หรือดีกว่า (ดูหัวข้อ 'ตำแหน่งของเครื่องหมายคำพูดคู่' ด้านล่าง):
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
ตัวแปรแรก (ใช้เพียง?
) ต้องตั้งค่าสถานะ แต่ STATE = "" (สตริงว่าง) คือตกลง - ไม่ใช่สิ่งที่คุณต้องการอย่างแน่นอน แต่เป็นทางเลือกและสัญลักษณ์เก่า
ชุดตัวเลือกที่สอง (ใช้:?
) ต้องการ DEST ที่จะตั้งค่าและไม่ว่างเปล่า
หากคุณไม่มีข้อความเชลล์จะแสดงข้อความเริ่มต้น
${var?}
สร้างกลับมาแบบพกพารุ่น 7 UNIX และบอร์นเชลล์ (1978 หรือราว) การ${var:?}
สร้างล่าสุดเล็กน้อย: ฉันคิดว่ามันอยู่ใน System III UNIX ประมาณปี 1981 แต่มันอาจจะอยู่ใน PWB UNIX ก่อนหน้านั้น ดังนั้นจึงอยู่ใน Korn Shell และใน POSIX เชลล์รวมถึง Bash โดยเฉพาะ
มันมักจะบันทึกไว้ในหน้าคนเปลือกในส่วนที่เรียกว่าการขยายตัวพารามิเตอร์ ตัวอย่างเช่นbash
คู่มือบอกว่า:
${parameter:?word}
แสดงข้อผิดพลาดถ้า Null หรือ Unset หากพารามิเตอร์เป็นโมฆะหรือไม่มีการตั้งค่าการขยายตัวของคำ (หรือข้อความไปยังผลกระทบที่ถ้าไม่มีคำ) จะถูกเขียนไปยังข้อผิดพลาดมาตรฐานและเปลือกถ้ามันไม่ได้โต้ตอบออกจาก มิฉะนั้นค่าของพารามิเตอร์จะถูกแทนที่
คำสั่งลำไส้ใหญ่
ฉันควรจะเพิ่มว่าคำสั่งโคลอนก็มีการประเมินผลอาร์กิวเมนต์แล้วก็ประสบความสำเร็จ มันเป็นสัญกรณ์แสดงความคิดเห็นเปลือกเดิม (ก่อน ' #
' ถึงจุดสิ้นสุดของบรรทัด) เป็นเวลานานสคริปต์เชลล์เป้าหมายมีเครื่องหมายทวิภาคเป็นอักขระตัวแรก C เชลล์จะอ่านสคริปต์และใช้อักขระตัวแรกเพื่อตรวจสอบว่าเป็นของ C เชลล์ ( #
แฮช '') หรือบอร์นเชลล์ (a ' :
' โคลอน) หรือไม่ จากนั้นเคอร์เนลก็เข้ามามีบทบาทและเพิ่มการรองรับความคิดเห็นของ ' #!/path/to/program
' และบอร์นเชลล์ได้รับ ' #
' และการประชุมลำไส้ใหญ่ก็อยู่ข้างทาง แต่ถ้าคุณเจอสคริปต์ที่ขึ้นต้นด้วยโคลอนตอนนี้คุณจะรู้ว่าทำไม
ตำแหน่งของเครื่องหมายคำพูดคู่
blongถามในความคิดเห็น :
มีความคิดเห็นเกี่ยวกับการสนทนานี้หรือไม่? https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749
ส่วนสำคัญของการอภิปรายคือ:
…อย่างไรก็ตามเมื่อฉันshellcheck
(เวอร์ชัน 0.4.1) ฉันได้รับข้อความนี้:
In script.sh line 13:
: ${FOO:?"The environment variable 'FOO' must be set and non-empty"}
^-- SC2086: Double quote to prevent globbing and word splitting.
คำแนะนำเกี่ยวกับสิ่งที่ฉันควรทำในกรณีนี้?
คำตอบสั้น ๆ คือ "ทำตามคำshellcheck
แนะนำ":
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
เพื่อแสดงเหตุผลว่าทำไมจึงศึกษาสิ่งต่อไปนี้ โปรดทราบว่า:
คำสั่งไม่ได้สะท้อนข้อโต้แย้งของมัน (แต่เชลล์ทำการประเมินข้อโต้แย้ง) เราต้องการที่จะเห็นการขัดแย้งดังนั้นโค้ดด้านล่างการนำมาใช้ประโยชน์ในสถานที่ของprintf "%s\n"
:
$ mkdir junk
$ cd junk
$ > abc
$ > def
$ > ghi
$
$ x="*"
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
abc
def
ghi
$ unset x
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
bash: x: You must set x
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
bash: x: You must set x
$ x="*"
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
*
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
abc
def
ghi
$ x=
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$ unset x
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$
โปรดสังเกตว่าค่าใน$x
ถูกขยายเป็นอันดับแรก*
จากนั้นรายการของชื่อไฟล์เมื่อนิพจน์โดยรวมไม่อยู่ในเครื่องหมายคำพูดคู่ นี่คือสิ่งที่shellcheck
แนะนำควรได้รับการแก้ไข ฉันยังไม่ได้ตรวจสอบว่ามันไม่ได้คัดค้านรูปแบบที่การแสดงออกถูกล้อมรอบด้วยเครื่องหมายคำพูดคู่ แต่มันก็เป็นข้อสันนิษฐานที่สมเหตุสมผลว่ามันจะตกลง