Apakah "$ {PS1-}" sintaks yang valid dan apa bedanya dengan polos "$ PS1"?

12

Saya melihat skrip yang memiliki:

if [ "${PS1-}" ]; then

Trailing itu -sedikit mengganggu saya karena sepertinya tidak ada sintaks standar Posix atau Bash. Apakah ini sintaks yang misterius yang telah ada selamanya, atau apakah itu salah ketik? Referensi ke standar / dokumen akan dihargai.

Biasanya saya akan kode itu:

if [ "$PS1" ]; then

Mana yang lebih benar atau apakah ada perbedaan di antara mereka?

Gregor
sumber

Jawaban:

12

Ini jelas sintaks POSIX . Parafrase:

Menggunakan ${parameter-word}, jika parameterada

  • atur dan bukan nol, lalu gantikan dengan nilai parameter,
  • atur tetapi null, lalu gantilah null, dan
  • tidak disetel, lalu gantilah word.

Sesi contoh:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

"Null" di sini berarti string kosong. Tidak ada nilai null khusus di shell POSIX, berbeda dengan SQL, misalnya.

Ini juga didokumentasikan di bagian "Parameter Perluasan" dari man bash.

l0b0
sumber
1
Saya kira halaman bash dan dash tidak lengkap, karena mereka tidak menyebutkan sintaks ini (aneh)!
Gregor
1
@ Gregor Kedua manual menyebutkan ini. Di manual Bash ada di paragraf sebelum daftar ekspansi parameter, dan di manual Dash ada di paragraf setelah.
Kusalananda
1
OK, "Menghilangkan titik dua ...." Saya tidak melihat bahwa :(
Gregor
zshadalah satu-satunya cangkang yang saya tahu yang menyebutkan varian bebas-usus secara eksplisit, bukan hanya membuat catatan tentang apa yang dilakukan penghilangan usus besar.
chepner
1
@pts, teks dalam POSIX cukup banyak menggunakan istilah "null", yang mungkin menjelaskan penggunaannya di halaman manual.
ilkkachu
23

Ekspansi variabel ${parameter:-word}akan menggunakan nilai $parameterjika disetel dan non-null (bukan string kosong), jika tidak maka akan menggunakan string word.

Menghilangkan :tidak akan menguji apakah nilainya kosong, hanya apakah itu tidak disetel atau tidak.

Ini berarti bahwa ${PS1-}akan memperluas ke nilai $PS1jika diatur, tetapi ke string kosong jika itu kosong atau tidak disetel. Dalam hal ini, ini adalah persis sama seperti ${PS1:-}sebagai string setelah -juga kosong.

Perbedaan antara "${PS1-}"dan "$PS1"halus, seperti yang dicatat oleh @Rakesh Sharma: keduanya akan diperluas ke nilai $PS1, atau ke string kosong jika tidak disetel. Pengecualiannya adalah ketika set -usedang aktif, dalam hal ini memperluas variabel yang tidak disetel akan menyebabkan kesalahan . Nilai default (kosong) yang diatur oleh "${PS1-}"circumvents this, memperluas unset PS1ke string kosong tanpa kesalahan.

Ini adalah sintaks standar ( berasal dari shell Bourne di akhir 70-an ), seperti halnya beberapa ekspansi serupa lainnya.

Kusalananda
sumber
Dan karena itu dikutip, itu sama dengan "$PS1", karena jika PS1kosong, itu kosong, dan kutipan menjaga kata dari menghilang sepenuhnya.
ilkkachu
4
Selama set -utidak berlaku. Ketika opsi nounset diaktifkan, maka "$ PS1" => memberikan kesalahan. "$ {PS-}" tidak akan.
@ SakeshSharma, itu adalah poin yang bagus. Sintaks yang berbeda sebenarnya dapat menghasilkan hasil yang berbeda tergantung pada opsi nounset, jadi, tes ["$ {parameter-}"] mungkin lebih benar!
Gregor
1
@ Kusalananda: Harap dicatat bahwa ${parameter:-word}akan menggunakan nilai $parameterjika NON-NULL. Dalam semua kasus lain (artinya: setel tetapi NULL atau tidak disetel) itu akan digunakan word. Kata-kata Anda:if its set or null
@ikkachu: Ya itu benar. Hanya ketika variabel set AND nonnull= = gunakan itu sendiri. Selain itu, ( set but NULL OR unset) => gunakan kata.
6

Sintaksnya:

${parameter:-word}

dan bentuk khusus:

${parameter-word}

adalah sintaks yang valid dalam shell POSIX , berarti menggunakan nilai default wordjika parametertidak disetel atau null.


Biasanya, dengan wordkosong, maka:

${parameter-}

dan:

$parameter

atau:

${parameter}

adalah setara.

Tetapi di bawah pengaruh set -u, semua variabel yang tidak disetel menyebabkan shell dihentikan. ${parameter-}digunakan untuk memotong aturan ketat itu. Ini berfungsi dalam kedua kasus jadi ya, itu cara yang lebih benar.

cuonglm
sumber