Apa arti dari substitusi $ {! Var_name + x}?


Jawaban:


17

Dalam bashshell, ${!var}adalah tipuan variabel. Itu memperluas ke nilai variabel yang namanya disimpan $var.

Ekspansi variabel ${var+value}adalah ekspansi POSIX yang berkembang ke valuejika variabel vardiatur (tidak peduli apakah nilainya kosong atau tidak).

Menggabungkan ini, ${!var+x}akan diperluas ke xjika variabel yang namanya disimpan $vardiatur.

Contoh:

$ foo=hello
$ var=foo
$ echo "${!var+$var is set, its value is ${!var}}"
foo is set, its value is hello
$ unset foo
$ echo "${!var+$var is set, its value is ${!var}}"

(baris kosong sebagai output)


Fungsi dalam pertanyaan dapat disingkat menjadi

check_if_variable_is_set () { [ -n "${!1+x}" ]; }

atau bahkan:

check_if_variable_is_set () { [ -v "$1" ]; }

atau bahkan:

check_if_variable_is_set()[[ -v $1 ]]

Di mana -vadalah bashtes pada nama variabel yang akan menjadi kenyataan jika variabel bernama diatur, dan false jika tidak.


POSIXly, itu bisa ditulis:

check_if_variable_is_set() { eval '[ -n "${'"$1"'+x}" ]'; }

Perhatikan bahwa semua itu adalah potensi kerentanan injeksi perintah jika argumen pada fungsi itu bisa berakhir di bawah kendali seorang penyerang. Coba misalnya dengan check_if_variable_is_set 'a[$(id>&2)]'.

Untuk mencegah hal itu, Anda mungkin ingin memverifikasi bahwa argumen adalah nama variabel yang valid terlebih dahulu. Untuk variabel:

check_if_variable_is_set() {
  case $1 in
    ("" | *[![:alnum:]_]* | [![:alpha:]_]*) false;;
    (*)  eval '[ -n "${'"$1"'+x}" ]'
  esac
}

(catatan yang [[:alpha:]]akan memeriksa karakter alfabet di lokal Anda sementara beberapa shell hanya menerima karakter alfabet dari karakter portabel yang diatur dalam variabel mereka)


Tidak ada yang lebih lengkap di dunia ini selain ini. Anda berhak mendapatkan cookie untuk itu.
Karim Manaouil

@KarimManaouil Sepertiga dari kue itu pergi ke Stéphane :-)
Kusalananda
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.