Cevap olarak kabuk komut dosyası içinde yorumlarla ilgili bu soruya , belirtilmektedir :
açıkça hiçbir şey yapmaz (ama yorumlar için kullanılacak değildir) boş komuttur.
Kesinlikle hiçbir şey yapmayan bir komutun faydası ne olurdu?
Cevap olarak kabuk komut dosyası içinde yorumlarla ilgili bu soruya , belirtilmektedir :
açıkça hiçbir şey yapmaz (ama yorumlar için kullanılacak değildir) boş komuttur.
Kesinlikle hiçbir şey yapmayan bir komutun faydası ne olurdu?
Yanıtlar:
Genelde true
döngülerde kullanırım ; Bence daha açık:
while true; do
...
done
:
Gerçekten kullanışlı bulduğum tek yer , bir şeyi eşleştirmeniz gerekiyorsa, ancak bir şey yapmak istemiyorsanız, durum ifadeleridir. Örneğin:
case $answer in
([Yy]*) : ok ;;
(*) echo "stop."; exit 1 ;;
esac
true
bir durum :
için, bir NOP için.
case a in a ) ;; esac
. Bunu kabul etmeyen kabukları var mı?
case ${var} in value);; *) do_something;; esac
kabul edilebilir. :
Komut boş durumlar için gerekli değildir.
Başlangıçta, C derlenmiş programın aksine bir Bourne kabuğu programı olduğunu belirlemek için kullanılmıştır. Bu, shebang ve çoklu betik dillerinden önceydi (csh, perl). Sadece ile başlayan bir betiği çalıştırabilirsiniz :
:
$ echo : > /tmp/xyzzy
$ chmod +x /tmp/xyzzy
$ ./xyzzy
Genellikle betiği $SHELL
(veya /bin/sh
) 'ye karşı çalıştırır .
O zamandan beri, temel kullanım argümanları değerlendirmektir. Hala kullanıyorum:
: ${EDITOR:=vim}
bir komut dosyasında varsayılan bir değer belirlemek için.
:
içinden sonlandırılması gereken döngüler yazmak için kullanışlıdır.
while :
do
...stuff...
done
Bu break
ya exit
da çağrılmadıkça sonsuza kadar çalışacak ya da kabuk bir sonlandırma sinyali alacaktır .
while true; do ...; done
Niyetleri okuyucuya daha iyi ilettiğini hissediyorumwhile :; do ...; done
Kabuk komut dosyasında "bir" ifadesi istediğinizde, ya bazı testler için sakıncalı görünebilecek bir "değil" koşulu kullanırsınız ya da yan tümcesinde gerçek kodda ':' kullanırsınız. fıkra.
if [ some-exotic-condition ]
then
:
else
# Real code here
fi
"Egzotik durum", olumsuzlamak istemediğiniz bir şey olabilir veya "negatif mantık" kullanmazsanız, bu çok daha net bir şekilde ortaya çıkabilir.
autoconf
bir varsayılan eklemek :
durumun nasıl tersine çevrileceğini bulmaktan daha kolay olduğu için oluşturulan komut dosyalarında da gösterilir .
!
Önüne yapışmanın ne kadar saçma olduğunu göremiyorum [ some-exotic-condition ]
, ama : else
ondan saçma değil sonra gereksiz .
!
Belirteci bütün bir komut boru elemanının ortadan kaldırır. while ! grep ... ; do ... done
veya if ! [ ... ] ; then ... fi
. Temel olarak test/[]
sözdiziminde dışsaldır. Bkz .: pubs.opengroup.org/onlinepubs/9699919799/utilities/…
Bunu sadece # karakterine ek olarak, bir satırın geçici olarak yorumlanması için # karakterine ek olarak kullandım; satırın yorumlanmasında, boş bir komut sırasına izin vermeme kabuğundaki bir hata nedeniyle satırın yorumlanmasında bir sözdizimi hatası oluştu. :
if condition ; then
:# temporarily commented out command
fi
Bunlar olmadan: bir sözdizimi hatası olan eksik bir komut dizisine sahibiz.
:
Yararlı bulduğum iki durum var :
#!/bin/sh
# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"
Bu, kabuk betiğinizin kullanıcılarının betiği düzenlemeden bir ayarı geçersiz kılmalarına izin vermenin uygun bir yoludur. (Bununla birlikte, komut satırı argümanları daha iyidir çünkü kullanıcı, dışa aktarılan ortamında kullandığınız değişkeni rastlantısal olarak kullanıyorsa, beklenmeyen davranış riskiyle karşılaşmazsınız.) Kullanıcı ayarı geçersiz kılar:
VAR="other value" ./script
${VAR=value}
Sözdizimi setine diyor VAR
üzere value
eğer VAR
zaten ayarlı değil, daha sonra değişkenin değerine genişler. Henüz değişkenin değerini önemsemediğimiz için, no-op komutundan :
kurtulmak için bir argüman olarak iletilir .
:
İşlemsiz bir komut olsa da , :
komut çalıştırılmadan önce kabuk tarafından genişleme gerçekleştirilir ( komut değil !), :
Böylece değişken ataması hala gerçekleşir (eğer varsa).
Ayrıca true
bunun yerine başka bir komutun kullanılması da kabul edilebilir :
, ancak niyetin daha az açık olması nedeniyle kodun okunması zorlaşır.
Aşağıdaki komut dosyası da işe yarar:
#!/bin/sh
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"
Ancak yukarıdakilerin korunması çok daha zordur. Bu satırın ${VAR}
üstünde bir satır kullanılıyorsa , printf
varsayılan atama genişletmesinin taşınması gerekir. Geliştirici bu ödevi taşımayı unutursa, bir hata tanıtılır.
Boş koşullu bloklardan genellikle kaçınılmalıdır, ancak bazen yararlı olurlar:
if some_condition; then
# todo: implement this block of code; for now do nothing.
# the colon below is a no-op to prevent syntax errors
:
fi
Bazı insanlar boş bir gerçek if
bloğa sahip olmanın kodu okumayı testten daha kolay yapmaktan daha kolaylaştırabileceğini iddia eder . Örneğin:
if [ -f foo ] && bar || baz; then
:
else
do_something_here
fi
tartışmasız okumaktan daha kolaydır:
if ! [ -f foo ] || ! bar && ! baz; then
do_something_here
fi
Bununla birlikte, boş bir gerçek bloktan daha iyi birkaç alternatif yaklaşım olduğuna inanıyorum:
Durumu bir fonksiyona koyun:
exotic_condition() { [ -f foo ] && bar || baz; }
if ! exotic_condition; then
do_something_here
fi
Koşulu küme parantezlerinin (veya parantezlerin içine koyun, ancak parantez alt alt işlem oluşturur) ve alt kabuk içindeki ortamda yapılan değişiklikler alt kabukların dışında görünmez):
if ! { [ -f foo ] && bar || baz; } then
do_something_here
fi
Yerine ||
kullanın if
:
[ -f foo ] && bar || baz || {
do_something_here
}
Tepkime şartlar gibi basit bir tek astar olduğunda bu yaklaşımı tercih ederim:
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$@"; exit 1; }
[ -f foo ] && bar || baz || fatal "condition not met"
UNIX'in eski versiyonlarındaki eski burur öncesi kabuğunda, :
komut başlangıçta etiketin belirlenmesi için tasarlanmıştı goto
(girişi etiketin bulunduğu yere bağlayan ayrı bir komuttu, bu yüzden etiketler ayrı bir sözdizimi olamazdı). Kabuk if
, ayrıca ayrı bir komut olduğunu da biliyor .) Yakında yorumlar için kullanıldı, daha önce bir yorum sözdizimi ( #
geri alma için kullanılıyordu) ve bu günler her şey kadar uyumluluk için buralardaydı.
Hiçbir şey yapmayan bir ifade olarak kullanmaya ek olarak, tek ifadeleri yorumlamak için bunları argümanlara dönüştürerek kullanabilirsiniz:.
: echo write this line > myfile
Hala boş bir dosya oluşturacağından tam olarak yorumda bulunmayacak .
:
olduğu DEĞİL yeterli yorumlama mekanizması.