Bir komut için ortam değişkenini belirleme


24

Belirli bir değerle çalıştırmak ENV_VAR=value commandiçin koşabilirim . Unset için eşdeğeri nedir ?commandENV_VARENV_VARcommand


7
Kenara: commandaslında orada beri tutucuların talihsiz seçimdir olan yerleşik bir o isimde komuta. mycommandya somecommandda böyle bir şey içeri girmek için daha iyi bir alışkanlık olabilir.
Charles Duffy

@CharlesDuffy, genellikle cmdbunun için kullanırım.
Stéphane Chazelas

Yanıtlar:


35

-iTüm ortamı silen seçenek dışında , POSIX envbir değişkeni çözmek için hiçbir yol sağlamaz.

Ancak, birkaç envuygulamada ( busyboxen azından GNU'lar ve 'FreeBSD'ler dahil ) şunları yapabilirsiniz:

env -u ENV_VAR command

ENV_VARDeğişkenlerin her bir örneğini ortamdan kaldırmakta işe yarar (boş bir ada sahip ortam değişkeni için işe yaramamasına dikkat edin ( env -u ''ya bir hata verir ya da herkes env '=value'bir sınırlama kabul etse bile uygulamaya bağlı olarak etkisizdir). unsetenv()( putenv()) için böyle bir sınırlama olmasa da, POSIX’in boş dize için bir hata döndürmesini gerektiren C işlevi tarafından ortaya çıkar .

Taşınabilir (POSIX kabuklarında) şunları yapabilirsiniz:

(unset -v ENV_VAR; exec command)

(bazı kabuklarda, çalıştırmanın exechangisinin commandçalışacağını değiştirebileceğini unutmayın : örneğin bir işlev ya da yerleşik yerine dosya sistemindeki bir dosyayı çalıştırır (ve aliasaçıkça envgörüldüğü gibi genişletme işlemini atlar). .

Ancak bu, bir kabuk değişkeniyle eşleştirilemeyen bir adı olan ortam değişkenleri için işe yaramaz (bazı kabukların mksh, başlangıçta zaten bu değişkenleri ortamdan çıkartacağını unutmayın ) veya salt okunur olarak işaretlenmiş değişkenler.

-vBourne kabuğu içindir ve bashkimin unsetolmadan -vbir unset olabilir ENV_VAR işlevi yok oldu ki değişken bu isimde. Diğer kabukları, -fseçeneği geçmediğiniz sürece işlevlerini ayarlayamazsınız . (pratikte bir fark yaratma olasılığı düşüktür).

(Ayrıca hata / misfeature dikkat bash/ mksh/ yasholan unset, bir durum değişkeni kaldırılır olmayabilir, ama altında bir dış kapsamında değişken ortaya )

Varsa perl, şunları yapabilirsiniz:

perl -e 'delete $ENV{shift@ARGV}; exec @ARGV or die$!' ENV_VAR command

Boş bir isim ile çevre değişkeni için bile çalışacak

Şimdi tüm bu olmaz eser, bir yerleşiği veya fonksiyon için bir ortam değişkeni değiştirmek istiyorum ve olduğu gibi onları bir kabuktaki çalıştırmak istemiyorsanız bash:

env -u LANG printf -v var %.3f 1.2 # would run /usr/bin/printf instead
(unset -v LANG; printf -v var %.3f 1.2) # changes to $var lost afterwards

(burada LANG'ın .ondalık ayırıcı olarak kullanıldığından ve anlaşıldığından emin olunmasında yanlış yönlendirilmiş bir yaklaşım olarak tanımlanması. Bunun için kullanılması daha iyi olur LC_ALL=C printf...)

Bazı kabuklarda, işlevini kullanarak değişken için yerel bir kapsam oluşturabilirsiniz:

without() {
  local "$1" # $1 variable declared as initially unset in bash¹
  shift
  "$@"
}
without LANG printf -v var %.3f 1.2

Bununla birlikte zsh, adsız bir işlevi de kullanabilirsiniz:

(){local ENV_VAR; command}

Bu yaklaşım bazı localdeğişkenlerde işe yaramaz (Almquist kabuğuna dayananlar gibi), değişkeni başlangıçta ayarlanmamış (ancak değeri ve özellikleri miras alır) ilan etmez. Bunlarda yapabilirsin local ENV_VAR; unset ENV_VAR, ama bunu yapmayın mkshya da yash( typesetbunun yerine local) işe yaramayacak, unsetsadece iptal etmek olacaktır local.

¹ Ayrıca bashyerel ENV_VARayarların (ayarlanmamış olsa bile) dışa aktarma özelliğini koruyacağına dikkat edin . Öyleyse command, bir değer atayan bir işlev ENV_VARolsaydı, değişken daha sonra çağrılan komutların ortamında mevcut olurdu. unset ENV_VARbu niteliği temizleyecekti. Veya local +x ENV_VARtemiz bir sayfa da sağlayabilecek bir kullanım kullanabilirsiniz (bu değişken salt okunur olarak bildirilmediyse, ancak bunun hakkında yapabileceğiniz hiçbir şey yoktur bash).


1
Bu ayrı bir soru, ancak boş bir isim olan bir ortam değişkeni nedir ve bir çeşit istismar için bile nasıl kullanırsınız? Çevreyi okuyan ve özellikle buna benzer bir program arayan bir program yazmak zorunda kalmaz mıydınız?
Joe

@Joe, örneğin dene env '=foo' python -c 'import os; print os.environ[""]'. Birçok insanın böyle bir değişken ayarlamak isteyeceğini sanmıyorum.
Stéphane Chazelas

9

Bildiğim kadarıyla doğrudan bir eşdeğeri yok; Bir alt kabuk kullanabilirsiniz:

(unset ENV_VAR; exec command)

(unset ENV_VAR; exec somecommand)Verimliliğin orijinaline eşdeğer olmak istiyorsanız (alt kabuğu tüketerek). Olduğu gibi, bu ekstra bir çatal ekler.
Charles Duffy

1
@Charles, her ne kadar bazı kabuklar bunu otomatik olarak yaparsa da, subshell commandçağrısındaki son komut budur.
Stephen Kitt

+1 çünkü bu yol etkileşimli kullanım için yazmak kolaydır. Bir kabuk için kabuk ortamındaki bir kerelik değişiklikler için alt kabuklar kullandığımı hatırlamak yerine kullanıyorum env -u.
Peter Cordes

0

Kullanabilirsiniz ENV_VAR= command

Bu aslında değişkeni ayarlamaz, ancak birçok durumda faydalı olabilir (kabuk komut dosyaları genellikle sadece test -nbir değişkenin ayarlanıp ayarlanmadığını kontrol etmek için kullanılır ):

$ export ENV_VAR=foo
$ mycommand
ENV_VAR: foo
$ ENV_VAR=bar mycommand
ENV_VAR: bar
$ ENV_VAR= mycommand
ENV_VAR: 
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.