การกำหนดค่าเริ่มต้นให้กับตัวแปรเชลล์ด้วยคำสั่งเดียวใน bash


685

ฉันมีการทดสอบทั้งหมดเกี่ยวกับตัวแปรในสคริปต์เชลล์ bash (3.00) ซึ่งหากไม่ได้ตั้งค่าตัวแปรไว้มันจะกำหนดค่าเริ่มต้นเช่น:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

ฉันดูเหมือนจะจำได้ว่ามีไวยากรณ์ในการทำเช่นนี้ในหนึ่งบรรทัดสิ่งที่คล้ายกับผู้ประกอบการที่ประกอบไปด้วยตัวอย่างเช่น:

FOO=${ ${VARIABLE} : 'default' }

(แม้ว่าฉันรู้ว่าจะไม่ทำงาน ... )

ฉันบ้าหรือว่ามีอะไรอย่างนั้นอยู่จริง?


1
ส่วนการขยายตัวเชลล์ Parameter ของการอ้างอิงเปลือกทุบตีเป็นที่ดีเริ่มต้นสถานที่: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions
Kemin Zhou

1
เอกสารประกอบ Gnu.org สำหรับการขยายพารามิเตอร์ของเชลล์ (คำใบ้: มีสิ่งดีๆอีกมากมายที่คุณสามารถทำได้!)
JDB ยังจดจำโมนิก้าได้

คำตอบ:


1230

ใกล้มากกับสิ่งที่คุณโพสต์จริงๆแล้ว:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.

หรือซึ่งจะกำหนดdefaultให้VARIABLEเช่นกัน:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.

64
หากฉันต้องการพบสิ่งนี้ในเอกสารประกอบสิ่งที่จะเป็น google สำหรับ Googling ที่มีอักขระพิเศษเช่น $ {: -} ไม่ใช่เรื่องง่าย
Joshua Olson

20
ในการตอบสนองต่อ solarmist: "ค่าเริ่มต้นการมอบหมายตัวแปร bash" ให้ฉันไปที่หน้านี้และค้นหาหน้าคู่มือของ bash ด้วย 'ตัวแปรตูด' พาฉันไปยังส่วนที่ถูกต้องหลังจาก ~ ห้า 'ถัดไป'
Mooshu

57
โปรดทราบว่ามันไม่ได้เฉพาะทุบตีและจะทำงานร่วมกับทั้งเปลือกครอบครัว ปลอดภัยสำหรับสคริปต์ทั่วไป
Jocelyn delalande

16
@solarmist คำสำคัญคือ "การขยายพารามิเตอร์ bash" หากคุณต้องการค้นหาเพิ่มเติมเกี่ยวกับมันและสหายของมัน
duleshi

20
นี่คือคำอธิบายเชิงลึกเพิ่มเติมเกี่ยวกับหัวข้อunix.stackexchange.com/a/122848/2407
jottr

290

สำหรับอาร์กิวเมนต์บรรทัดคำสั่ง:

VARIABLE=${1:-DEFAULTVALUE}    

ซึ่งกำหนดให้VARIABLEกับค่าของอาร์กิวเมนต์ที่ 1 ที่ส่งผ่านไปยังสคริปต์หรือมูลค่าของDEFAULTVALUEถ้าไม่มีการโต้แย้งดังกล่าวถูกส่งผ่าน


245

ถ้าตัวแปรเหมือนกันแล้ว

: "${VARIABLE:=DEFAULT_VALUE}"

กำหนด DEFAULT_VALUE ให้กับ VARIABLE หากไม่ได้กำหนดไว้ เครื่องหมายคำพูดคู่ป้องกันการแยกและการแยกคำ

ดูที่หัวข้อ 3.5.3 การขยายพารามิเตอร์เชลล์ในคู่มือ Bash


27
เคล็ดลับที่ยุ่งยากนี้ไม่ชัดเจนสำหรับฉันโดยใช้: ไม่มีเอฟเฟ็กต์ในตัวเพื่อกินการขยายตัวของ $ {.. } แต่ออกจากชุดที่หลากหลาย จนถึงตอนนี้ฉันกำลังทำสิ่งนี้: VARIABLE = "$ {ตัวแปร: -DEFAULT_VALUE}" และรู้สึกว่าใช้กับตัวแปรได้หลายครั้ง
dino

ปรากฎว่าสิ่งนี้ไม่ได้ทำงานอยู่เสมอสำหรับตัวแปร BASH-BUILTIN มันแปลกมาก ๆ ขณะนี้ผู้ที่รู้จักฉันคือHISTTIMEFORMAT
Otheus

ฉันจะตั้งค่าเริ่มต้นหลายค่าได้อย่างไร ฉันลองใช้ ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}" แต่ดูเหมือนว่าจะไม่ทำงาน ...
Hans

8
@ ฮัน: โคลอนเป็นคำสั่ง (ซึ่งไม่ทำอะไรเลย) และดังนั้นจึงจำเป็นเพียงครั้งเดียว เช่น: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik

36

แม้คุณสามารถใช้เช่นค่าเริ่มต้นค่าของตัวแปรอื่น

มีไฟล์ defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2

เรียกใช้./defvalue.sh first-value second-valueเอาต์พุต

first-value
second-value

และเรียกใช้./defvalue.sh first-valueเอาต์พุต

first-value
first-value


26

เพื่อตอบคำถามของคุณและในการแทนที่ตัวแปรทั้งหมด

echo "$\{var}"
echo "Substitute the value of var."


echo "$\{var:-word}"
echo "If var is null or unset, word is substituted for var. The value of var does not change."


echo "$\{var:=word}"
echo "If var is null or unset, var is set to the value of word."


echo "$\{var:?message}"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."


echo "$\{var:+word}"
echo "If var is set, word is substituted for var. The value of var does not change."

18

FWIW คุณสามารถให้ข้อความแสดงข้อผิดพลาดดังนี้:

USERNAME=${1:?"Specify a username"}

สิ่งนี้แสดงข้อความเช่นนี้และออกด้วยรหัส 1:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username

ตัวอย่างที่สมบูรณ์ยิ่งขึ้นของทุกสิ่ง:

#!/bin/bash
ACTION=${1:?"Specify 'action' as argv[1]"}
DIRNAME=${2:-$PWD}
OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"

เอาท์พุท:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION รับค่าของอาร์กิวเมนต์แรกและออกหากว่างเปล่า
  • $DIRNAME เป็นอาร์กิวเมนต์ที่ 2 และมีค่าเริ่มต้นเป็นไดเรกทอรีปัจจุบัน
  • $OUTPUT_DIRเป็นอาร์กิวเมนต์ที่ 3 หรือ$HOMEDIR(ถ้ากำหนดไว้) /tmpอื่น สิ่งนี้ใช้ได้กับ OS X แต่ฉันก็ไม่แน่ใจว่ามันพกพาได้

17

จากนั้นก็มีวิธีในการแสดง 'if' ของคุณสร้างขึ้นอย่างเข้มงวดยิ่งขึ้น:

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}

10

นี่คือตัวอย่าง

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"

บันทึกสิ่งนี้เป็น script.sh และทำให้สามารถเรียกใช้งานได้ เรียกใช้โดยไม่มี params

./script.sh
> value: [default_value]

รันด้วย param

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