Koşarsam
export TEST=foo
echo $TEST
Foo çıktılar.
Koşarsam
TEST=foo echo $TEST
O değil. Dışa aktarma veya bir komut dosyası kullanmadan bu işlevi nasıl alabilirim?
Koşarsam
export TEST=foo
echo $TEST
Foo çıktılar.
Koşarsam
TEST=foo echo $TEST
O değil. Dışa aktarma veya bir komut dosyası kullanmadan bu işlevi nasıl alabilirim?
Yanıtlar:
Bunun nedeni, kabuğun gerçekte komutu çalıştırmadan önce komut satırındaki değişkeni genişletmesidir ve o sırada değişken yoktur. Eğer kullanırsan
TEST=foo; echo $TEST
Çalışacak.
export
değişkeni daha sonra yürütülen komutların ortamında görünmesini sağlar (bunun bash nasıl göründüğü için help export
). Yalnızca bir komutun ortamında görünmek için değişkene ihtiyacınız varsa, denediğinizi kullanın, örneğin:
TEST=foo your-application
$TEST
, komut satırı çalıştırılmadan önce genişler . Çalıştığında echo
(ayrıca echo
genellikle kabuk yerleşik komutuna çevirip çevirmeyeceğine de dikkat edin /bin/echo
) ortamında ayarlanan değişkeni görür. Bununla birlikte, değişken içeriğini ortamından çıkarmayı echo $TEST
söylemez . Kabuğa, şu anda denilen değişkende her ne olduğu ile tartışarak çalışmasını söyler - ve bunlar çok farklı şeylerdir. echo
TEST
echo
TEST
var=value sh -c 'echo "$var"'
?
sh -c
) alt kabuk tarafından yapılır.
Ortam değişkenlerinden ziyade, sınırlı bir kapsam için kabuk değişkenlerine sahip olmak istediğinizden şüpheleniyorum . Ortam değişkenleri, yürütüldüklerinde komutlara iletilen dizelerin bir listesidir .
İçinde
var=value echo whatever
var=value
Dize yankının aldığı ortama geçiriyorsunuz . Ancak, echo
çevre listesinde herhangi bir şey yapmaz ve yine de çoğu kabukta, echo
yerleşiktir ve bu nedenle yürütülmez .
Yazmış olsaydın
var=value sh -c 'echo "$var"'
Bu başka bir konu olurdu. Burada, geçiriyorsanız var=value
için sh
komuta ve sh
çevresini kullanmak oluyor. Kabuklar, çevrelerinden aldıkları değişkenlerin her birini kabuk değişkenine dönüştürür, böylece var
ortam değişkeni sh
bir $var
değişkene dönüştürülür ve bu echo
komut satırında genişlediğinde , olur echo value
. Çevre miras varsayılan olarak olduğundan, echo
ayrıca alacak var=value
ortamındaki (veya infaz edildi olsaydı), ama yine echo
çevre umursamıyor.
Şimdi, şüphelendiğimde, istediğiniz şey kabuk değişkenlerinin kapsamını sınırlamaksa, birkaç olası yaklaşım vardır.
Taşınabilir (Bourne ve POSIX):
(var=value; echo "1: $var"); echo "2: $var"
Yukarıdaki (...) bir alt kabuk başlatır (çoğu kabukta yeni bir kabuk işlemi), bu nedenle orada bildirilen herhangi bir değişken yalnızca bu alt kabuğu etkileyecektir, bu nedenle yukarıdaki kodun "1: değer" vermesini beklerdim. ve "2:" veya "2: önceden belirlenmiş her neyse".
Bourne benzeri mermilerin çoğunda, işlevleri ve "yerel" yerleşimi kullanabilirsiniz:
f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"
Zsh ile satır içi işlevleri kullanabilirsiniz:
(){ local var=value; echo "1: $var"; }; echo "2: $var"
veya:
function { local var=value; echo "1: $var"; }; echo "2: $var"
Bash ve zsh ile (ancak kül, pdksh veya AT&T ksh ile değil), bu numara da işe yarıyor:
var=value eval 'echo "1: $var"'; echo "2: $var"
Birkaç kabuklarda çalışan bir varyant ( dash
, mksh
, yash
), ancak zsh
(içinde olmadıkça sh
/ ksh
öykünme):
var=value command eval 'echo "1: $var"'; echo "2: $var"
( POSIX mermilerinde command
(burada eval
) özel bir yapının önünü kullanarak uzmanlıklarını kaldırır (burada bunlardan gelen değişken atamaları geri döndükten sonra etkin kalır)
Doğru yapıyorsunuz, ancak bash sözdiziminin yanlış yorumlanması kolaydır: bunun env var getirmesine echo $TEST
neden olduğunu echo
ve TEST
sonra yazdırdığını düşünebilirsiniz , değil. Verilen
export TEST=123
sonra
TEST=456 echo $TEST
aşağıdaki diziyi içerir:
Kabuk tüm komut satırını ayrıştırır ve tüm değişken değişkenlerini çalıştırır, böylece komut satırı olur.
TEST=456 echo 123
Komuttan önce ayarlanan temp değişkenlerini yaratır, böylece mevcut değerini kaydeder TEST
ve 456 ile üzerine yazar; komut satırı şimdi
echo 123
Bu durumda 123'ü stdout'a basan kalan komutu çalıştırır (bu yüzden kalan shell komutu temp değerini bile kullanmaz TEST
)
Değerini geri yükler TEST
Değişken ikame gerektirmediğinden, yerine printenv kullanın:
>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
printenv
Kavramı test etmek / kanıtlamak için faydalı buldum (aksine bir senaryo gibi davranır echo
)
Bu çalışmayı aşağıdakileri kullanarak alabilirsiniz:
TEST=foo && echo $TEST
TEST=foo
ayrı bir ifade olarak çalışıyor - sadece bağlamında ayarlanmadı echo
.