Parametre Genişletme
Açık cevap, parametre genişletmenin özel formlarından birini kullanmaktır:
: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}
Veya daha iyisi (aşağıdaki 'Çift tırnakların konumu' bölümüne bakın):
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
İlk varyant (sadece kullanarak ?
) STATE ayarlanmasını gerektirir, ancak STATE = "" (boş bir dize) TAMAM - tam olarak ne istediğinizi değil, alternatif ve eski gösterimi.
İkinci varyant (kullanma :?
) DEST'in ayarlanmasını ve boş olmamasını gerektirir.
Herhangi bir mesaj sağlamazsanız, kabuk varsayılan bir mesaj sağlar.
${var?}
Yapı, Versiyon 7 UNIX ve Bourne Shell (1978 veya oralarda) taşınabilir geri döndü. ${var:?}
Ben 1981 dolaylarında Sistem III UNIX içinde olduğunu düşünüyorum, ama bundan önce PWB UNIX içinde olabilir: yapı biraz daha yenidir. Bu nedenle Korn Shell'de ve özellikle Bash dahil POSIX mermilerinde.
Genellikle kabuğun kılavuz sayfasında Parametre Genişletme adlı bir bölümde belgelenir . Örneğin, bash
el kitabı şöyle diyor:
${parameter:?word}
Null veya Unet ise Hata görüntüler. Parametre null veya unset ise, sözcüğün genişletilmesi (veya sözcük yoksa bu etkiye yönelik bir mesaj) standart hataya yazılır ve kabuk, etkileşimli değilse çıkar. Aksi takdirde, parametrenin değeri değiştirilir.
Kolon Komutanlığı
Muhtemelen iki nokta üst üste komutunun argümanlarını değerlendirdiğini ve başarılı olduğunu eklemeliyim. Orijinal kabuk yorum göstergesidir (' #
' öncesinde satır sonuna kadar). Uzun bir süre, Bourne kabuk betiklerinde ilk karakter olarak iki nokta üst üste vardı. C Kabuğu bir komut dosyasını okur ve C Kabuğu (bir ' #
' karma) veya Bourne kabuğu (bir ' :
' iki nokta üst üste) için olup olmadığını belirlemek için ilk karakteri kullanır . Daha sonra çekirdek harekete geçti ve ' #!/path/to/program
' ve Bourne kabuğu ' ' için destek ekledi #
ve kolon konvansiyonu yol kenarına gitti. Ancak iki nokta üst üste ile başlayan bir senaryo ile karşılaşırsanız, şimdi nedenini bileceksiniz.
Çift tırnakların konumu
blong bir yorumda sordu :
Bu tartışma hakkında bir fikriniz var mı? https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749
Tartışmanın özü:
… Ancak, ben shellcheck
(0.4.1 sürümü ile), bu mesajı alıyorum:
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.
Bu durumda ne yapmam gerektiğine dair bir tavsiye var mı?
Kısa cevap " shellcheck
önerdiği gibi yap":
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Nedenini göstermek için aşağıdakileri inceleyin. :
Komutun bağımsız değişkenlerini yinelemediğini unutmayın (ancak kabuk bağımsız değişkenleri değerlendirir). Argümanları görmek istiyoruz, bu yüzden aşağıdaki kod printf "%s\n"
yerine kullanıyor :
.
$ 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
$
İçindeki değerin önce nasıl $x
genişletildiğine *
ve ardından genel ifade çift tırnak içinde olmadığında dosya adlarının bir listesine dikkat edin. shellcheck
Önerilmesi gereken budur . İfadenin çift tırnak içine alındığı forma itiraz etmediğini doğrulamamıştım, ancak iyi olacağı makul bir varsayım.