bash menetapkan nilai default

135

$ {parameter: = word} Tetapkan Nilai Default. Jika parameter tidak disetel atau null, perluasan kata ditetapkan ke parameter. Nilai parameter kemudian diganti. Parameter posisi dan parameter khusus mungkin tidak ditetapkan dengan cara ini.

Saya pikir saya bisa menggunakan fitur ini untuk menulis, ${LONG_VARIABLE_NAME:=hello}bukan lebih lama LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}, tetapi sekarang bash juga mencoba mengeksekusi 'halo' dan itu memberikan perintah yang tidak ditemukan. Adakah cara untuk menghindarinya? Atau apakah saya harus tetap pada yang terakhir? Adakah yang bisa memberi contoh di mana penetapan default benar-benar bermanfaat?

zedoo
sumber
13
Saat mengutip teks, sebaiknya menyertakan tautan ke sumbernya.
Jonathon Reinhart

Jawaban:

202

Gunakan titik dua:

: ${A:=hello}

Usus besar adalah perintah nol yang tidak melakukan apa-apa dan mengabaikan argumennya. Itu dibangun ke bash sehingga proses baru tidak dibuat.

camh
sumber
93
Saya tidak bisa tidak mengamati itu : ${A:=hello}persis selama A=${A:-hello}. Tampaknya yang terakhir ini sedikit kurang esoteris dan tujuannya lebih jelas. Menggunakan :, yang pada dasarnya adalah no-op, nampak murung jika dibandingkan dengan cara OP melakukannya sebelumnya.
Dan Moulding
5
@camh: Setuju. Saya dapat melihat di mana, jika Anda memiliki banyak variabel untuk diinisialisasi ke default dan mereka memiliki nama yang panjang, :pendekatannya akan lebih baik, baik untuk mengetik dan membaca. Ya, ini sepertinya area di mana Bash dapat menggunakan sedikit peningkatan.
Dan Moulding
17
@DanMoulding: bagaimana dengan : ${VERY_LONG_VARIABLE_NAME:=hello}vs VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. : . Saya harap Anda menggunakan nama variabel deskriptif dalam kode Anda :)
pihentagy
18
Tidak hanya lebih pendek, tapi kurang rawan kesalahan: VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}. Ups.
chepner
5
Keuntungan dari A=$A:-hellopendekatan ini adalah bahwa pendokumentasian diri ketika dijalankan dengan set -x. Artinya, tugas akan mencetak sebagai A=hellosedangkan perintah nol hanya akan mencetak nilai ( hello).
Penduduk asli
107

Silakan lihat http://www.tldp.org/LDP/abs/html/parameter-substitution.html untuk contoh

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

Jika parameter tidak disetel, gunakan default. Setelah panggilan, parameter masih belum disetel.
Kedua bentuk itu hampir setara. Ekstra :membuat perbedaan hanya ketika parameter telah dideklarasikan, tetapi nol.

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}

Jika parameter tidak disetel, tetapkan nilai parameter ke default.
Kedua bentuknya hampir setara. The: membuat perbedaan hanya ketika parameter telah dinyatakan dan bernilai nol

# 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}

Jika parameter ditetapkan, gunakan alt_value, jika tidak gunakan string nol. Setelah panggilan, nilai parameter tidak berubah.
Kedua bentuknya hampir setara. The: membuat perbedaan hanya ketika parameter telah dinyatakan dan bernilai nol

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
Jonathan L.
sumber
20

Perluasan parameter nilai default sering berguna dalam membangun skrip seperti contoh di bawah ini. Jika pengguna hanya memanggil skrip apa adanya, perl tidak akan dibangun. Pengguna harus secara eksplisit mengatur WITH_PERLke nilai selain "tidak" untuk memilikinya dibangun.

$ 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

Bangun tanpa Perl

$ ./defvar.sh
not building with perl

Bangun dengan Perl

$ WITH_PERL=yes ./defvar.sh
building with perl
SiegeX
sumber