Apa maksudnya: $ {param: = value}?

34

Saya membaca berikut ini di Panduan Pengguna untuk Z-Shell :

Sinonim untuk 'true' adalah ':'; sering digunakan dalam formulir ini untuk memberikan argumen yang memiliki efek samping tetapi yang tidak boleh digunakan - sesuatu seperti

: ${param:=value}

yang merupakan ungkapan umum dalam semua turunan shell Bourne. Dalam ekspansi parameter, $paramdiberikan nilai nilai jika kosong sebelumnya, dan dibiarkan sendiri sebaliknya. Karena itu adalah satu-satunya alasan ekspansi parameter, Anda menggunakan :untuk mengabaikan argumen. Sebenarnya, shell dengan riang membangun baris perintah - titik dua, diikuti oleh apa pun nilainya $param, apakah penugasan terjadi atau tidak - kemudian menjalankan perintah; Kebetulan bahwa ':' tidak memperhatikan argumen yang diberikan.

tapi saya tidak mengerti. Saya mengerti :artinya true, tetapi ada dua titik dua dalam ekspresi. Sebagai pertanyaan kecil, mengapa idiom ini banyak digunakan dalam semua turunan shell Bourne? Apa tujuannya?

Catatan: Saya tertarik dengan apa yang dilakukan idiom ini di bash dan di zsh .

Terima kasih

Amelio Vazquez-Reina
sumber
Apakah Anda meminta zshatau bash?
enzotib
@enzotib, saya tertarik pada keduanya. Saya mengklarifikasi itu.
Amelio Vazquez-Reina

Jawaban:

31

Mari kita hancurkan ini menjadi beberapa bagian.

Kode ini menjalankan perintah :dengan beberapa argumen. Perintah :tidak melakukan apa-apa dan mengabaikan argumennya. Oleh karena itu seluruh baris perintah tidak melakukan apa pun, kecuali efek samping apa pun yang terjadi dalam argumen.

Sintaksnya ${parameter_name:=value}ada di semua kerang gaya Bourne non-antik, termasuk abu, bash, ksh dan zsh. Ini menetapkan parameter ke default jika perlu. Ini setara dengan

if [ -z "$parameter_name" ]; then parameter_name=value; fi
 ${parameter_name}

Dengan kata lain, jika parameter_nametidak disetel atau disetel ke nilai kosong, maka setel ke nilai yang ditunjukkan; dan kemudian jalankan perintah, menggunakan nilai parameter baru. Ada varian,, ${parameter_name=value}yang membiarkan parameter kosong jika kosong, hanya menggunakan nilai yang ditunjukkan jika parameter tidak disetel.

Anda akan menemukan sintaks ini didokumentasikan di bawah "ekspansi parameter" dalam spesifikasi POSIX , dan manual dash, bash, ksh, dan zsh.

Ada variasi pada sintaks ini, khususnya ${parameter_name:-value}yang memungkinkan Anda menggunakan nilai default untuk ekspansi ini saja, tanpa menetapkan parameter.

Singkatnya, : ${parameter_name:=value}adalah cara penulisan yang ringkas

if [ -z "$parameter_name" ]; then parameter_name=value; fi
Gilles 'SANGAT berhenti menjadi jahat'
sumber
11

:tidak berarti benar - Anda mungkin berpikir while :, tetapi bahkan dalam ungkapan itu tidak berarti "benar", itu hanya terjadi untuk mengevaluasi itu (pada kenyataannya, itu hanyalah perintah nol, atau noop).

Ekspansi parameter ini ( ${x:=y}) berarti "menetapkan y ke x jika x tidak disetel atau kosong, dan perluas ke y ".

$ echo "${foo:=bar}"
bar
$ foo=baz
$ echo "${foo:=bar}"
baz
$ foo=
$ echo "${foo:=bar}"
bar
$ echo "${foo}"
bar

Wiki Peretas Bash memiliki artikel bagus tentang perluasan parameter di sini .

Alasan yang :digunakan adalah agar sementara bagian lain dari perintah dievaluasi, mereka tidak ditindaklanjuti (seperti halnya :perintah nol). Jadi, Anda telah ${x:=y}menjalankan fungsinya tanpa memengaruhi yang lain, misalnya, jika Anda tidak memilikinya :di awal, ia akan mencoba menjalankan perintah yang disebut y .

Inilah bashhalaman bantuan pada ::

:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Chris Down
sumber
3

Yang pertama :adalah perintah, itu disebut "noop" atau "no operation". Seperti yang dikatakan di halaman manual, sering digunakan untuk mengevaluasi argumen.

Yang kedua :adalah kualifikasi dalam ekspansi variabel - secara teknis itu :=. Yang seperti dikatakan, ini menetapkan nilai jika tidak memiliki nilai.

Secara idiom, jika Anda membutuhkan nilai default variabel lingkungan, maka Anda dapat menggunakan sintaks ini. Misalnya, saat menjalankan program cron(8), lingkungan tidak diatur dan dan file dot shell tidak berjalan. Jadi, Anda mungkin perlu mengatur beberapa default.

: ${JAVA_HOME:=/usr/local/jdk-1.6.0_28}

Kemudian Anda dapat 'mengatur dan melupakannya' (sampai jvm default berubah).

Arcege
sumber