Menetapkan nilai default ke variabel shell dengan satu perintah di bash

690

Saya memiliki sejumlah besar tes pada variabel dalam skrip shell bash (3,00) di mana jika variabel tidak disetel, maka itu menetapkan default, misalnya:

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

Sepertinya saya ingat ada beberapa sintaks untuk melakukan ini dalam satu baris, sesuatu yang menyerupai operator ternary, misalnya:

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

(meskipun saya tahu itu tidak akan berhasil ...)

Apakah saya gila, atau ada sesuatu seperti itu ada?

Edward Q. Bridges
sumber
1
Bagian Ekspansi Parameter Shell dari referensi shell bash adalah tempat awal yang baik: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou
1
Dokumentasi Gnu.org untuk Shell Parameter Expansion (petunjuk: ada banyak hal keren lainnya yang dapat Anda lakukan!)
JDB masih mengingat Monica

Jawaban:

1232

Sangat dekat dengan apa yang Anda posting, sebenarnya:

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

Atau, yang akan menetapkan defaultuntuk VARIABLEjuga:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.
Andrew McGregor
sumber
64
Jika saya ingin menemukan ini di dokumentasi, untuk apa google? Googling dengan karakter khusus seperti $ {: -} tidak mudah.
Joshua Olson
20
Menanggapi solarmist: "default tugas bash variabel" izinkan saya ke halaman ini, dan mencari halaman manual bash dengan 'variabel ass' membuat saya ke bagian kanan setelah ~ lima 'berikutnya'
Mooshu
57
Perhatikan bahwa ini bukan khusus untuk bash dan akan bekerja dengan seluruh keluarga shell. Aman untuk skrip generik.
Jocelyn delalande
16
@solarmist Kata kuncinya adalah "ekspansi parameter bash", jika Anda ingin menemukan lebih banyak tentang hal itu dan teman-temannya.
duleshi
20
Berikut adalah penjelasan yang lebih mendalam tentang topik unix.stackexchange.com/a/122848/2407
jottr
290

Untuk argumen baris perintah:

VARIABLE=${1:-DEFAULTVALUE}    

yang menetapkan VARIABLEnilai argumen pertama yang diteruskan ke skrip atau nilai DEFAULTVALUEjika tidak ada argumen yang diloloskan.

miku
sumber
245

Jika variabelnya sama, maka

: "${VARIABLE:=DEFAULT_VALUE}"

menetapkan DEFAULT_VALUE ke VARIABEL jika tidak ditentukan. Kutipan ganda mencegah globbing dan pemisahan kata.

Juga lihat Bagian 3.5.3, Ekspansi Parameter Shell , dalam manual Bash.

Hans Ginzel
sumber
27
Trik rumit ini tidak jelas bagi saya, menggunakan: no-effect builtin untuk memakan ekspansi $ {..} TETAPI meninggalkan set VARIABEL. Sampai sekarang saya sedang melakukan ini: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" dan merasa konyol karena menggunakan VARIABEL dua kali.
dino
Ternyata INI TIDAK SELALU BEKERJA UNTUK VARIABEL BASH-BUILTIN. Sangat sangat aneh. Saat ini yang saya kenal adalahHISTTIMEFORMAT
Otheus
bagaimana cara menetapkan beberapa nilai default? Saya mencoba ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}" tapi itu sepertinya tidak berhasil ...
Hans
8
@Hans: Usus besar adalah perintah (yang tidak melakukan apa-apa) dan dengan demikian diperlukan hanya sekali. Misalnya: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik
36

Bahkan Anda dapat menggunakan nilai default seperti nilai dari variabel lain

memiliki file defvalue.sh

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

echo $variable1
echo $variable2

jalankan ./defvalue.sh first-value second-valueoutput

first-value
second-value

dan jalankan ./defvalue.sh first-valueoutput

first-value
first-value
Montells
sumber
28

lihat di bawah 3.5.3 (ekspansi parameter shell)

jadi dalam kasus Anda

${VARIABLE:-default}
ghostdog74
sumber
26

Untuk menjawab pertanyaan Anda dan semua penggantian variabel

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."
Guru
sumber
18

FWIW, Anda dapat memberikan pesan kesalahan seperti:

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

Ini menampilkan pesan seperti ini dan keluar dengan kode 1:

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

Contoh yang lebih lengkap dari semuanya:

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

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

Keluaran:

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

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION mengambil nilai argumen pertama, dan keluar jika kosong
  • $DIRNAME adalah argumen ke-2, dan default ke direktori saat ini
  • $OUTPUT_DIRadalah argumen ke-3, atau $HOMEDIR(jika didefinisikan), yang lain /tmp,. Ini berfungsi pada OS X, tapi saya tidak yakin itu portabel.
Curtis Mattoon
sumber
17

Lalu ada cara untuk mengekspresikan konstruksi 'jika' Anda lebih singkat:

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}
Rob Wells
sumber
10

Berikut ini sebuah contoh

#!/bin/bash

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

echo "value: [$value]"

simpan ini sebagai script.sh dan buat itu bisa dieksekusi. jalankan tanpa params

./script.sh
> value: [default_value]

jalankan dengan param

./script.sh my_value
> value: [my_value]
Assaf Shomer
sumber