bash กำหนดค่าเริ่มต้น


135

$ {พารามิเตอร์: = word} กำหนดค่าเริ่มต้น หากพารามิเตอร์ไม่ได้ตั้งค่าหรือว่างการขยายของคำจะถูกกำหนดให้กับพารามิเตอร์ จากนั้นค่าของพารามิเตอร์จะถูกแทนที่ ไม่สามารถกำหนดพารามิเตอร์ตำแหน่งและพารามิเตอร์พิเศษด้วยวิธีนี้

ฉันคิดว่าฉันสามารถใช้คุณสมบัตินี้ในการเขียน${LONG_VARIABLE_NAME:=hello}แทนการใช้งานได้นานขึ้นLONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}แต่ตอนนี้ bash ก็พยายามเรียกใช้ 'hello' และไม่พบคำสั่ง วิธีใดที่จะหลีกเลี่ยงสิ่งนั้น? หรือจะต้องติดที่หลัง? ใครสามารถยกตัวอย่างได้ว่าค่าเริ่มต้นของการกำหนดมีประโยชน์จริงหรือไม่?


13
เมื่ออ้างถึงข้อความการรวมลิงก์ไปยังแหล่งที่มาจะเป็นประโยชน์
Jonathon Reinhart

คำตอบ:


202

ใช้เครื่องหมายจุดคู่:

: ${A:=hello}

ลำไส้ใหญ่เป็นคำสั่ง null ที่ไม่ทำอะไรเลยและไม่สนใจอาร์กิวเมนต์ มันถูกสร้างขึ้นใน bash ดังนั้นกระบวนการใหม่จึงไม่ถูกสร้างขึ้น


94
ฉันอดไม่ได้ที่จะสังเกตว่า: ${A:=hello}มันยาวพอA=${A:-hello}ๆ ดูเหมือนว่าอย่างหลังจะลึกลับน้อยกว่าเล็กน้อยและเจตนาของมันชัดเจนมากขึ้น การใช้:ซึ่งโดยพื้นฐานแล้วไม่มีการใช้งานดูเหมือนจะเป็นสิ่งที่ไม่ดีเมื่อเปรียบเทียบกับวิธีที่ OP เคยทำมาก่อน
Dan Molding

5
@camh: เห็นด้วย ฉันสามารถดูได้ว่าถ้าคุณมีตัวแปรจำนวนมากที่จะเริ่มต้นเป็นค่าเริ่มต้นและมีชื่อยาว:วิธีนี้จะดีกว่าทั้งสำหรับการพิมพ์และการอ่าน ใช่ดูเหมือนว่านี่จะเป็นพื้นที่ที่ Bash สามารถปรับปรุงได้เล็กน้อย
แดนปั้น

17
@ DanMoulding: แล้ว: ${VERY_LONG_VARIABLE_NAME:=hello}เทียบกับ: VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. ฉันหวังว่าคุณจะใช้ชื่อตัวแปรที่สื่อความหมายในรหัสของคุณ :)
pihentagy

18
ไม่ได้เป็นเพียงสั้น VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}แต่ข้อผิดพลาดน้อย: อุ่ย
chepner

5
ข้อได้เปรียบของวิธีการก็คือว่าเอกสารตนเองเมื่อทำงานกับA=$A:-hello set -xนั่นคือการกำหนดจะพิมพ์ในA=helloขณะที่คำสั่ง null จะพิมพ์เฉพาะค่า ( hello)
lmsurprenant

109

โปรดดูที่http://www.tldp.org/LDP/abs/html/parameter-substitution.htmlสำหรับตัวอย่าง

${parameter-default}, ${parameter:-default}

หากไม่ได้ตั้งค่าพารามิเตอร์ให้ใช้ค่าเริ่มต้น หลังจากการโทรแล้วพารามิเตอร์ยังไม่ได้ตั้งค่า
ทั้งสองรูปแบบเกือบจะเทียบเท่ากัน ค่าพิเศษ:สร้างความแตกต่างเฉพาะเมื่อมีการประกาศพารามิเตอร์ แต่เป็นโมฆะ

unset EGGS
echo 1 ${EGGS-spam}   # 1 spam
echo 2 ${EGGS:-spam}  # 2 spam

EGGS=
echo 3 ${EGGS-spam}   # 3
echo 4 ${EGGS:-spam}  # 4 spam

EGGS=cheese
echo 5 ${EGGS-spam}   # 5 cheese
echo 6 ${EGGS:-spam}  # 6 cheese

${parameter=default}, ${parameter:=default}

หากไม่ได้ตั้งค่าพารามิเตอร์ให้ตั้งค่าพารามิเตอร์เป็นค่าเริ่มต้น
ทั้งสองรูปแบบเกือบเทียบเท่ากัน The: สร้างความแตกต่างเฉพาะเมื่อมีการประกาศพารามิเตอร์และเป็นโมฆะ

# sets variable without needing to reassign
# colons suppress attempting to run the string
unset EGGS
: ${EGGS=spam}
echo 1 $EGGS     # 1 spam
unset EGGS
: ${EGGS:=spam}
echo 2 $EGGS     # 2 spam

EGGS=
: ${EGGS=spam}
echo 3 $EGGS     # 3        (set, but blank -> leaves alone)
EGGS=
: ${EGGS:=spam}
echo 4 $EGGS     # 4 spam

EGGS=cheese
: ${EGGS:=spam}
echo 5 $EGGS     # 5 cheese
EGGS=cheese
: ${EGGS=spam}
echo 6 $EGGS     # 6 cheese

${parameter+alt_value}, ${parameter:+alt_value}

หากตั้งค่าพารามิเตอร์ให้ใช้ alt_value มิฉะนั้นให้ใช้สตริงว่าง หลังจากการโทรค่าพารามิเตอร์จะไม่เปลี่ยนแปลง
ทั้งสองรูปแบบเกือบเทียบเท่ากัน The: สร้างความแตกต่างเฉพาะเมื่อมีการประกาศพารามิเตอร์และเป็นโมฆะ

unset EGGS
echo 1 ${EGGS+spam}  # 1
echo 2 ${EGGS:+spam} # 2

EGGS=
echo 3 ${EGGS+spam}  # 3 spam
echo 4 ${EGGS:+spam} # 4

EGGS=cheese
echo 5 ${EGGS+spam}  # 5 spam
echo 6 ${EGGS:+spam} # 6 spam

20

การขยายพารามิเตอร์ค่าดีฟอลต์มักมีประโยชน์ในบิลด์สคริปต์เช่นตัวอย่างด้านล่าง หากผู้ใช้เพียงเรียกใช้สคริปต์ตามที่เป็นอยู่ perl จะไม่ถูกสร้างขึ้นผู้ใช้ต้องตั้งค่าอย่างชัดเจนWITH_PERLเป็นค่าอื่นที่ไม่ใช่ "ไม่" เพื่อให้มีอยู่ในตัว

$ cat defvar.sh
#!/bin/bash

WITH_PERL=${WITH_PERL:-no}

if [[ "$WITH_PERL" != no ]]; then
    echo "building with perl"
    # ./configure --enable=perl
else
    echo "not building with perl"
    # ./configure
fi

สร้างโดยไม่ต้อง Perl

$ ./defvar.sh
not building with perl

สร้างด้วย Perl

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