Ortam değişkenlerini ayarlamak için neden değişkenleri bir komutun öneki olarak kullanamıyorum?


11

Normalde, bir komut için önek olarak aşağıdaki gibi bir ortam değişkeni ayarlamak mümkündür:

hello=hi bash -c 'echo $hello'

Ayrıca aşağıdaki gibi bir komut çağrısının herhangi bir bölümünü değiştirmek için bir değişken kullanabileceğimizi biliyorum:

$ cmd=bash
$ $cmd -c "echo hi" # equivalent to bash -c "echo hi"

Bir ortam değişkeni ayarlamak için bir komut önek için bir değişken kullanamayacağını bulmak çok şaşırdım. Test durumu:

$ prefix=hello=hi
$ echo $prefix # prints hello=hi
$ $prefix bash -c 'echo $hello'
hello=hi: command not found

Ortam değişkenini neden bir değişken kullanarak ayarlayamıyorum? Önek bölümü özel bir bölüm mü? Önde eval kullanarak çalıştırabildim, ama yine de nedenini anlamıyorum. 4.4 bash kullanıyorum.


1
Sen kullanabilirsiniz envyerine evalIIRC daha güvenli, ancak daha yavaş olan.
wjandrea

Yanıtlar:


14

Bu dizinin sizi yakalayan kısmı olduğundan şüpheleniyorum:

Değişken atamaları veya yeniden yönlendirmeleri olmayan kelimeler genişletilir (bkz. Kabuk Genişletmeleri). Genişletmeden sonra herhangi bir sözcük kalırsa, ilk sözcük komutun adı olarak alınır ve geri kalan sözcükler bağımsız değişkenlerdir

Bu , Basit Komut Genişletme bölümündeki Bash referans kılavuzundan alınmıştır.

Olarak cmd=bash, örneğin, herhangi bir ortam değişkenleri ayarlanır ve deneme bırakarak parametre genişletilmesi yoluyla komut hattı işler bash -c "echo hi".

Olarak prefix=hello=hiişlem bir birinci kelime ile sonuçlanan, parametre devam böylece, örneğin, birinci geçişte herhangi bir değişken atamaları, daha vardır hello=hi.

Değişken atamaları işlendikten sonra, komut yürütme sırasında yeniden işlenmezler.

İşleme ve sonuçlarını aşağıdaki bölümlere bakın set -x:

$ prefix=hello=hi
+ prefix=hello=hi
$ $prefix bash -c 'echo $hello'
+ hello=hi bash -c 'echo $hello'
-bash: hello=hi: command not found
$ hello=42 bash -c 'echo $hello'
+ hello=42
+ bash -c 'echo $hello'
42

"Değişken genişleme" -as- "çevre değişkenleri" den daha güvenli bir varyasyon için, wjandrea'nın şu önerisinieval göz önünde bulundurun :env

prefix=hello=hi
env "$prefix" bash -c 'echo "$hello"'
hi

Bu, bir komut satırı değişken ataması değildir, çünkü envyardımcı programın bir komuta ortam değişkenleri atama ana işlevini kullanıyoruz , ancak aynı hedefi gerçekleştiriyor. $prefixDeğişken adı = değer sağlayan komut satırı işlenmesi esnasında genişletilir envyanında geçirir, bash.


3
Benzer şekilde, $foo=bar bash -c ...çalışmaz, çünkü $foo=bardeğişken atama (değeri ne olursa olsun $foo) $foo=bardeğildir , çünkü name=valuedeğişken atama modeline uymaz .
muru

3

Çünkü $prefixbir ödev değil. @ Jeff daha uzun bir açıklamaya sahiptir .

Bunun yerine bir işlevle benzer bir şey yapabilirsiniz:

$ prefix() { hello=hi "$@"; }
$ prefix bash -c 'echo "$hello"'
hi

... ve isterseniz bunları istifleyebilirsiniz:

$ foo() { foo=123 "$@"; }
$ bar() { bar=456 "$@"; }
$ foo bar bash -c 'echo "$bar $foo"'
456 123
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.