Penugasan variabel di luar pernyataan kasus


8

Dalam banyak bahasa dimungkinkan untuk menetapkan hasil dari pernyataan kasus / beralih ke variabel, daripada mengulangi penugasan variabel berkali-kali dalam pernyataan kasus. Apakah mungkin untuk melakukan hal seperti ini di shell Bash?

color_code=$(case "$COLOR" in
  (red)    1;;
  (yellow) 2;;
  (green)  3;;
  (blue)   4;;
esac)

(Atau, sebagai tambahan, di kulit lainnya?)


Anda memiliki tambahan (. Kalau tidak, tidak apa-apa.
HalosGhost

Jawaban:


6

The variable=$(...)membangun akan mengambil output standar perintah apa yang ada di $(...)dan menetapkan ke variable. Dengan demikian, untuk variableditugaskan seperti yang Anda inginkan, nilai-nilai harus dikirim ke output standar. Ini mudah dilakukan dengan echoperintah:

color_code=$(case "$COLOR" in
  red)    echo 1;;
  yellow) echo 2;;
  green)  echo 3;;
  blue)   echo 4;;
esac)

Ini akan bekerja pada bashserta semua kerang POSIX lainnya.

Opsional Left Parens

Menurut standar POSIX, paren kiri dalam casepernyataan adalah opsional dan yang berikut juga berfungsi:

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Seperti yang ditunjukkan Gilles dalam komentar, tidak semua shell menerima kedua formulir dalam kombinasi dengan $(...): untuk tabel kompatibilitas yang sangat rinci, lihat "$ ()" substitusi perintah vs. tertanam ")" .


Satu halaman yang saya periksa (saya tidak ingat di mana tempatnya) mencantumkan pembukaan (sebagai opsional. Saya pikir itu mungkin membantu menghindari membiarkan )salah ditafsirkan sebagai penutup )untuk $(...)ekspresi.
iconoclast

@iconoclast Ya. Pembukaan (adalah opsional: kode berfungsi sama tanpa atau tanpa mereka. Saya meninggalkan mereka hanya karena, baik atau buruk, itu adalah tradisi. Bagian penting dari solusi yang diusulkan adalah penggunaan echo.
John1024

1
@iconoclast Kerang yang lebih lama (pra-POSIX) tidak mengizinkan pembukaan (untuk casepola, tetapi beberapa kerang melakukannya dan membutuhkan pembukaan (ketika casedigunakan dalam substitusi perintah. Kerang modern baik-baik saja. Lihat di-ulm.de/~mascheck/various/cmd-subst
Gilles 'SO- stop being evil'

1
@Gilles Terima kasih atas info itu. Kedalaman pengetahuan Anda, seperti biasa, mengesankan.
John1024

2

color_code=$(…)menugaskan output dari perintah ke variabel color_code, dengan baris baru dilucuti. Jadi, Anda perlu menghasilkan beberapa output. Kode yang Anda tulis mencoba dieksekusi 1sebagai perintah.

Anda bisa menggunakan idiom ini. Catatan yang color_codeakan kosong jika $COLORtidak ada nilai yang didukung.

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Tapi itu tidak terlalu idiomatis. Bahasa shell diarahkan untuk kombinasi sederhana dari perintah sederhana. Substitusi perintah besar ini canggung. Substitusi perintah membuat subkulit, yang lebih lambat daripada metode langsung:

case "$COLOR" in
  red)    color_code=1;;
  yellow) color_code=2;;
  green)  color_code=3;;
  blue)   color_code=4;;
esac

Perbedaan semantik utama antara dua pendekatan adalah yang $(…)menciptakan subkulit, sehingga setiap penugasan, keluar, redirection, dll. Yang dilakukan di dalam tidak memiliki efek di luar.

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.