Gán các giá trị mặc định cho các biến shell bằng một lệnh duy nhất trong bash


682

Tôi có cả đống bài kiểm tra về các biến trong tập lệnh shell bash (3.00) trong đó nếu biến không được đặt, thì nó sẽ gán mặc định, ví dụ:

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

Tôi dường như nhớ lại có một số cú pháp để thực hiện điều này trong một dòng, một cái gì đó tương tự như một toán tử ternary, ví dụ:

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

(mặc dù tôi biết rằng nó sẽ không hoạt động ...)

Tôi điên, hay một cái gì đó như thế tồn tại?


1
Phần mở rộng tham số Shell của tham chiếu shell bash là nơi khởi đầu tốt: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou

1
Tài liệu của Gnu.org cho việc mở rộng tham số Shell (gợi ý: có rất nhiều thứ hay ho khác bạn có thể làm!)
JDB vẫn còn nhớ Monica

Câu trả lời:


1225

Rất gần với những gì bạn đã đăng, thực sự:

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

Hoặc, cũng sẽ gán defaultcho VARIABLE:

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

64
Nếu tôi muốn tìm thấy điều này trong tài liệu, google sẽ làm gì? Googling với các ký tự đặc biệt như $ {: -} không dễ dàng gì.
Joshua Olson

20
Để trả lời cho người hòa giải: "mặc định gán biến bash" hãy cho tôi đến trang này và tìm kiếm trang hướng dẫn của bash với 'biến ass' đã đưa tôi đến phần bên phải sau ~ năm 'tiếp theo'
Mooshu

57
Lưu ý rằng nó không đặc trưng cho bash và sẽ hoạt động với toàn bộ họ vỏ. Nó an toàn cho các tập lệnh chung.
Jocelyn delalande

16
@solarmist Từ khóa là "bash mở rộng tham số", nếu bạn muốn tìm hiểu thêm về nó và các bạn đồng hành của nó.
duleshi

20
Dưới đây là một lời giải thích sâu hơn về chủ đề unix.stackexchange.com/a/122848/2407
jottr

288

Đối với các đối số dòng lệnh:

VARIABLE=${1:-DEFAULTVALUE}    

mà gán cho VARIABLE giá trị của đối số 1 được truyền cho tập lệnh hoặc giá trị DEFAULTVALUEnếu không có đối số đó được truyền.


243

Nếu biến giống nhau, thì

: "${VARIABLE:=DEFAULT_VALUE}"

gán DEFAULT_VALUE cho VARIABLE nếu không được xác định. Các trích dẫn kép ngăn chặn chia tách và tách từ.

Cũng xem Phần 3.5.3, Mở rộng tham số Shell , trong hướng dẫn Bash.


27
Thủ thuật khó khăn này không rõ ràng đối với tôi, bằng cách sử dụng: dựng sẵn không có hiệu lực để ăn phần mở rộng của $ {..} NHƯNG rời khỏi bộ VARIABLE. Cho đến bây giờ tôi vẫn đang làm điều này: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" và cảm thấy khó chịu khi sử dụng VARIABLE hai lần.
khủng long

Hóa ra NÀY KHÔNG LUÔN LÀM VIỆC CHO CÁC BIỂU TƯỢNG BASH-BUILTIN. Nó rất rất kỳ lạ. Hiện tại những người được biết đến với tôi làHISTTIMEFORMAT
Otheus

Làm cách nào để đặt nhiều giá trị mặc định? Tôi đã thử ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}" nhưng điều đó dường như không hoạt động ...
Hans

8
@Hans: Dấu hai chấm là lệnh (không làm gì cả) và do đó chỉ cần một lần. Ví dụ:: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik

34

Thậm chí bạn có thể sử dụng như giá trị mặc định giá trị của biến khác

có một tập tin defvalue.sh

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

echo $variable1
echo $variable2

chạy ./defvalue.sh first-value second-valueđầu ra

first-value
second-value

và chạy ./defvalue.sh first-valueđầu ra

first-value
first-value

27

xem ở đây dưới 3.5.3 (mở rộng tham số shell)

vì vậy trong trường hợp của bạn

${VARIABLE:-default}

25

Để trả lời câu hỏi của bạn và trên tất cả các thay thế biến

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."

17

FWIW, bạn có thể cung cấp một thông báo lỗi như vậy:

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

Điều này sẽ hiển thị một thông báo như thế này và thoát với mã 1:

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

Một ví dụ đầy đủ hơn về mọi thứ:

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

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

Đầu ra:

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

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION lấy giá trị của đối số đầu tiên và thoát nếu trống
  • $DIRNAME là đối số thứ 2 và mặc định cho thư mục hiện tại
  • $OUTPUT_DIRlà đối số thứ 3, hoặc $HOMEDIR(nếu được xác định), khác , /tmp. Điều này hoạt động trên OS X, nhưng tôi không chắc rằng nó có thể mang theo được.

16

Sau đó, có cách thể hiện 'nếu' của bạn xây dựng chặt chẽ hơn:

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

9

Đây là một ví dụ

#!/bin/bash

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

echo "value: [$value]"

lưu cái này dưới dạng script.sh và làm cho nó có thể thực thi được. chạy nó mà không cần thông số

./script.sh
> value: [default_value]

chạy nó với param

./script.sh my_value
> value: [my_value]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.