ไวยากรณ์ที่ถูกต้อง“ $ {PS1-}” และแตกต่างจากธรรมดา“ $ PS1” อย่างไร


12

ฉันกำลังดูสคริปต์ที่มี:

if [ "${PS1-}" ]; then

การติดตามนั้นทำให้-ฉันรำคาญเล็กน้อยเพราะดูเหมือนว่าจะไม่ได้ Posix หรือ Bash ไวยากรณ์มาตรฐาน นี่คือไวยากรณ์ที่ซ่อนเร้นอยู่ตลอดกาลหรือเป็นตัวพิมพ์ผิด การอ้างอิงใด ๆ ถึงมาตรฐาน / เอกสารจะได้รับการชื่นชม

ปกติฉันจะรหัสมัน

if [ "$PS1" ]; then

ข้อใดถูกกว่าหรือมีข้อแตกต่างระหว่างกัน

คำตอบ:


12

นี้แน่นอนไวยากรณ์ POSIX ถอดความ:

ใช้${parameter-word}ถ้าparameterเป็น

  • การตั้งค่าและไม่เป็นโมฆะแล้วแทนค่าของparameter,
  • ตั้งค่าเป็นโมฆะจากนั้นแทนค่าว่างและ
  • wordไม่มีการตั้งค่าแทนแล้ว

ตัวอย่างเซสชัน:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

"Null" ที่นี่หมายถึงสตริงที่ว่างเปล่า ไม่มีค่าว่างพิเศษใน POSIX เชลล์ตรงกันข้ามกับ SQL ตัวอย่างเช่น

นอกจากนี้ยังมีการระบุไว้ในส่วน "การขยายตัวพารามิเตอร์" man bashของ


1
ฉันเดาว่า bash และ dash man-pages นั้นไม่สมบูรณ์เพราะพวกเขาไม่ได้พูดถึงไวยากรณ์นี้ (แปลก)!
Gregor

1
@Gregor ทั้งสองคู่มือพูดถึงสิ่งนี้ ในคู่มือ Bash จะอยู่ในย่อหน้าก่อนรายการการขยายพารามิเตอร์และในคู่มือ Dash จะอยู่ในย่อหน้าหลัง
Kusalananda

1
ตกลง "ละเว้นโคลอน .... " ฉันไม่เห็นว่า :(
Gregor

zshเป็นเปลือกเดียวที่ฉันรู้ว่ากล่าวถึงพันธุ์ที่ปราศจากลำไส้ใหญ่อย่างชัดเจนมากกว่าเพียงแค่จดบันทึกสิ่งที่ละเว้นเครื่องหมายโคลอน
chepner

1
@pts ข้อความใน POSIX ใช้คำว่า "null" ซึ่งอาจอธิบายการใช้ใน man page
ilkkachu

23

การขยายตัวของตัวแปร${parameter:-word}จะใช้ค่าของ$parameterถ้ามันเป็นชุดและไม่ใช่ null (ไม่สตริงที่ว่างเปล่า) wordมิฉะนั้นจะใช้สตริง

การข้าม:จะไม่ทดสอบว่าค่าว่างเปล่าหรือไม่เท่านั้นไม่ว่าจะเป็นค่านั้น

ซึ่งหมายความว่า${PS1-}จะขยายเป็นค่า$PS1หากตั้งไว้ แต่เป็นสตริงว่างถ้าว่างหรือไม่ได้ตั้งค่า ในกรณีนี้เป็นเหมือนกันในฐานะ${PS1:-}เป็นสตริงหลังจากที่-ยังเป็นที่ว่างเปล่า

ความแตกต่างระหว่าง"${PS1-}"และ"$PS1"มีความละเอียดอ่อนตามที่ @Rakesh Sharma หมายเหตุ: ทั้งสองจะขยายเป็นค่าของ$PS1หรือเป็นสตริงว่างถ้ามันไม่มีการตั้งค่า ยกเว้นเมื่อset -uมีการใช้งานในกรณีที่การขยายตัวแปรล้างจะทำให้เกิดข้อผิดพลาด ค่าเริ่มต้น (ว่าง) ตั้งโดย"${PS1-}"หลีกเลี่ยงสิ่งนี้ขยายการตั้งค่าPS1เป็นสตริงว่างโดยไม่มีข้อผิดพลาด

นี่คือไวยากรณ์มาตรฐาน ( มีต้นกำเนิดในเชลล์เป้าหมายในช่วงปลายยุค 70 ) ซึ่งเป็นส่วนขยายอื่น ๆ ที่คล้ายกันสองสามรายการ


และเนื่องจากมันถูกยกมามันก็เหมือนกับ"$PS1"เมื่อPS1มันว่างเปล่ามันว่างเปล่าและคำพูดก็ไม่ได้หายไปโดยสิ้นเชิง
ilkkachu

4
ตราบใดที่set -uไม่มีผลบังคับใช้ เมื่อตัวเลือกคำนามเปิดอยู่ "$ PS1" => จะแสดงข้อผิดพลาด "$ {PS-}" จะไม่

@ RakeshSharma ที่เป็นจุดที่ดี ไวยากรณ์ที่แตกต่างกันสามารถให้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับตัวเลือกคำนามดังนั้นการทดสอบ ["$ {parameter-}"] อาจจะถูกต้องมากขึ้น!
Gregor

1
@ Kusalananda: โปรดทราบว่า${parameter:-word}จะใช้ค่า$parameterถ้าไม่ใช่ค่า NULL ในกรณีอื่น ๆ (หมายถึง: ทั้งชุด แต่เป็นโมฆะหรือไม่มีการตั้งค่า) wordจะใช้ ถ้อยคำของคุณ:if its set or null

@ikkachu: ใช่ถูกต้อง เฉพาะเมื่อตัวแปรคือset AND nonnull=> ใช้ตัวเอง. อื่น ๆ , ( set but NULL OR unset) => ใช้คำ

6

ไวยากรณ์:

${parameter:-word}

และรูปแบบพิเศษ:

${parameter-word}

เป็นไวยากรณ์ที่ถูกต้องใน POSIX เชลล์หมายถึงการใช้ค่าเริ่มต้นwordหากparameterไม่ได้ตั้งค่าหรือเป็นโมฆะ


โดยปกติด้วยwordว่างแล้ว:

${parameter-}

และ:

$parameter

หรือ:

${parameter}

เทียบเท่า

แต่ภายใต้ผลกระทบของset -uตัวแปร unset ทั้งหมดทำให้เชลล์ถูกยกเลิก ${parameter-}ถูกใช้เพื่อข้ามกฎที่เข้มงวดนั้น มันทำงานได้ทั้งสองกรณีดังนั้นใช่มันเป็นวิธีที่ถูกต้องมากขึ้น

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