Ekspansi Parameter
Jawaban yang jelas adalah menggunakan salah satu bentuk khusus dari ekspansi parameter:
: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}
Atau, lebih baik (lihat bagian 'Posisi kutipan ganda' di bawah):
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Varian pertama (hanya menggunakan ?) membutuhkan NEGARA yang akan ditetapkan, tetapi NEGARA = "" (string kosong) OK - tidak persis apa yang Anda inginkan, tetapi alternatif dan notasi yang lebih tua.
Varian kedua (menggunakan :?) membutuhkan DEST untuk diatur dan tidak kosong.
Jika Anda tidak memberikan pesan, shell menyediakan pesan default.
The ${var?}membangun portabel kembali ke Versi 7 UNIX dan Bourne Shell (1978 atau sekitar itu). The ${var:?}membangun sedikit lebih baru: Saya pikir itu di Sistem III UNIX sekitar tahun 1981, tetapi mungkin telah di PWB UNIX sebelum itu. Oleh karena itu di Shell Korn, dan di shell POSIX, termasuk Bash khusus.
Biasanya didokumentasikan dalam halaman manual shell di bagian yang disebut Parameter Expansion . Misalnya, bashmanual mengatakan:
${parameter:?word}
Tampilan Galat jika Null atau Unset. Jika parameter nol atau tidak disetel, perluasan kata (atau pesan ke efek itu jika kata tidak ada) ditulis ke kesalahan standar dan shell, jika tidak interaktif, keluar. Jika tidak, nilai parameter diganti.
Perintah Colon
Saya mungkin harus menambahkan bahwa perintah titik dua hanya memiliki argumen dievaluasi dan kemudian berhasil. Ini adalah notasi komentar shell asli (sebelum ' #' ke akhir baris). Untuk waktu yang lama, skrip Bourne shell memiliki tanda titik dua sebagai karakter pertama. C Shell akan membaca skrip dan menggunakan karakter pertama untuk menentukan apakah itu untuk C Shell ( #hash ') atau Bourne shell (a' :'colon). Kemudian kernel ikut serta dan menambahkan dukungan untuk ' #!/path/to/program' dan Bourne shell mendapat ' #' komentar, dan konvensi usus besar berjalan di pinggir jalan. Tetapi jika Anda menemukan skrip yang dimulai dengan titik dua, sekarang Anda akan tahu mengapa.
Posisi tanda kutip ganda
blong bertanya dalam komentar :
Ada pemikiran tentang diskusi ini? https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749
Inti dari diskusi ini adalah:
... Namun, ketika saya shellcheckmenggunakannya (dengan versi 0.4.1), saya menerima pesan ini:
In script.sh line 13:
: ${FOO:?"The environment variable 'FOO' must be set and non-empty"}
^-- SC2086: Double quote to prevent globbing and word splitting.
Adakah saran tentang apa yang harus saya lakukan dalam kasus ini?
Jawaban singkatnya adalah "lakukan seperti yang shellcheckdisarankan":
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Untuk mengilustrasikan alasannya, pelajarilah yang berikut ini. Perhatikan bahwa :perintah tersebut tidak menggemakan argumennya (tetapi shell mengevaluasi argumennya). Kami ingin melihat argumen, jadi kode di bawah ini digunakan printf "%s\n"sebagai pengganti :.
$ mkdir junk
$ cd junk
$ > abc
$ > def
$ > ghi
$
$ x="*"
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
abc
def
ghi
$ unset x
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
bash: x: You must set x
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
bash: x: You must set x
$ x="*"
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
*
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
abc
def
ghi
$ x=
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$ unset x
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$
Perhatikan bagaimana nilai dalam $xdiperluas menjadi pertama *dan kemudian daftar nama file ketika ekspresi keseluruhan tidak dalam tanda kutip ganda. Inilah yang shellcheckmerekomendasikan harus diperbaiki. Saya belum memverifikasi bahwa itu tidak keberatan dengan bentuk di mana ekspresi dilampirkan dalam tanda kutip ganda, tetapi itu adalah asumsi yang masuk akal bahwa itu akan baik-baik saja.