Anlamını alırken, bu cevapların hiçbirinin doğru olduğuna inanmıyorum. eval
hiçbir şekilde gerekli değildir ve değişkenlerinizi iki kez değerlendirmenize bile gerek yoktur.
Doğru, @Gilles çok yaklaşıyor, ancak değerleri geçersiz kılma sorununu ve birden fazla ihtiyacınız varsa nasıl kullanılması gerektiğini ele almıyor. Sonuçta, bir şablon birden fazla kullanılmalıdır, değil mi?
Bence bu onları değerlendirdiğiniz sıra önemli. Aşağıdakileri göz önünde bulundur:
ÜST
Burada bazı varsayılanlar ayarlayacak ve çağrıldığında yazdırmaya hazırlanacaksınız ...
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
ORTA
Bu, sonuçlarına göre yazdırma işlevinizi çağırmak için diğer işlevleri tanımladığınız yerdir ...
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
ALT
Artık her şeyi ayarladınız, işte burada sonuçlarınızı uygulayacak ve çekeceksiniz.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
SONUÇLAR
Nedenini birazdan anlatacağım, ancak yukarıdakileri çalıştırmak aşağıdaki sonuçları üretir:
_less_important_function()'s
ilk çalıştırma:
Annenin evine gittim ve Disney on Ice'ı gördüm .
Bunu yaparsanız kaligrafiyi başarılı olacaktır.
sonra _more_important_function():
Mezarlığa gittim ve Disney on Ice'ı gördüm.
Bunu yaparsanız iyileştirici matematik başarılı olacaktır.
_less_important_function()
tekrar:
Mezarlığa gittim ve Disney on Ice'ı gördüm.
Düzeltici matematik yaparsanız pişman olacaksınız .
NASIL ÇALIŞIR:
Buradaki temel özellik, conditional ${parameter} expansion.
bir değişkeni bir değere yalnızca form kullanılarak ayarlanmamış veya boşsa ayarlayabilirsiniz:
${var_name
: =desired_value}
Bunun yerine yalnızca ayarlanmamış bir değişken ayarlamak isterseniz, :colon
ve null değerleri olduğu gibi kalacaktır.
KAPSAMDA:
Yukarıdaki örnekte fark edilebilir $PLACE
ve zaten çağrılmış olsa bile $RESULT
üzerinden ayarlandığında değişebilir , muhtemelen çalıştırıldığında onları ayarlayabilirsiniz. Bunun işe yaramasının nedeni bir işlevdir - diğerleri için kullanılandan ziyade içine aldım . Alt kabukta çağrıldığından, ayarladığı her değişken üst kabuğuna döndüğünde bu değerler kaybolur.parameter expansion
_top_of_script_pr()
_top_of_script_pr()
( subshelled )
parens
{ curly braces }
locally scoped
Ancak _more_important_function()
setler $ACTION
olduğu zaman , ikinci setin değerlendirmesini globally scoped
etkiler çünkü setler sadece_less_important_function()'s
$ACTION
_less_important_function()
$ACTION
${parameter:=expansion}.
:BOŞ
Ve lider kullanmak niçin :colon?
Kuyusu, man
sayfa söyleyecektir : does nothing, gracefully.
Görüyorsunuz, parameter expansion
o - bu gibi sesler tam olarak ne expands
değerine ${parameter}.
So ile bir değişkeni ayarladığınızda ${parameter:=expansion}
biz değeri ile sol - hangi kabuk irade satır içi yürütmeyi deneyin. Çalıştırmaya çalıştıysa the cemetery
, size bazı hatalar tükürecekti. PLACE="${PLACE:="the cemetery"}"
aynı sonuçları üretirdi, ancak bu durumda da gereksizdir ve kabuğun: ${did:=nothing, gracefully}.
Bunu yapmanıza izin verir:
echo ${var:=something or other}
echo $var
something or other
something or other
BURADA-BELGELER
Ve bu arada - null veya unset değişkeninin satır içi tanımı da aşağıdakilerin neden işe yaradığıdır:
<<HEREDOC echo $yo
${yo=yoyo}
HEREDOC
yoyo
Bir düşünmenin en iyi yolu here-document
A'yı girdi dosya tanımlayıcısına akış olarak gerçek bir dosyadır. Aşağı yukarı bunlar budur, ancak farklı mermiler onları biraz farklı uygular.
Her durumda, teklif vermezseniz <<LIMITER
bunu bir şekilde akmaktadır olsun ve için değerlendirilir expansion.
bir bir değişkeni bildirerek So here-document
teneke işleri, ancak yalnızca yoluyla expansion
hangi yalnızca önceden ayarlanmamış değişkenleri ayarlayarak sizi sınırlar. Yine de, tanımladığınız gibi ihtiyaçlarınıza tam olarak uyar, çünkü şablon yazdırma işlevinizi çağırdığınızda varsayılan değerleriniz her zaman ayarlanır.
NEDEN OLMASIN eval?
Sunmuş olduğum örnek, kabul etmenin güvenli ve etkili bir parameters.
yolunu sunar Kapsamı işlediğinden, üzerinden ayarlanan her değişken ${parameter:=expansion}
dışarıdan tanımlanabilir. Yani, tüm bunları template_pr.sh adlı bir komut dosyasına koyarsanız ve çalıştırırsanız:
% RESULT=something_else template_pr.sh
Şunları elde edersiniz:
Annenin evine gittim ve Disney on Ice'ı gördüm
Kaligrafi yaparsanız bir şey yaparsınız
Mezarlığa gittim ve Disney on Ice'ı gördüm
Düzeltici matematik yaparsanız
Mezarlığa gittim ve Disney on Ice'ı gördüm
Düzeltici matematik yaparsanız
Bu, komut dosyasında tam anlamıyla ayarlanan değişkenler için işe yaramaz, örneğin $EVENT, $ACTION,
ve $one,
ancak ben sadece farkı göstermek için bu şekilde tanımladım.
Her durumda, bir evaled
ifadeye bilinmeyen girdilerin kabulü doğal olarak güvensizdir, oysa parameter expansion
bunu yapmak için özel olarak tasarlanmıştır.