Komut arasındaki fark nedir
$ env FOO=bar baz
ve
$ FOO=bar baz
Ne etkisi env
var?
Komut arasındaki fark nedir
$ env FOO=bar baz
ve
$ FOO=bar baz
Ne etkisi env
var?
Yanıtlar:
İşlevsel olarak eşdeğerdirler.
Ana fark, env FOO=bar baz
kabuk baz
ile FOO=bar baz
kabuğun doğrudan çağırdığı yerde kabuk arasında bir ara işlem başlatılmasını içerir baz
.
Yani bu açıdan FOO=bar baz
tercih edilir.
Kendimi kullanırken bulduğum tek durum env FOO=bar
, başka bir komuta komut iletmem gereken yer.
Belirli bir örnek olarak, ortamın bazı değişikliklerini yapan ve daha sonra exec
kendisine iletilen komutu çağıran bir sarmalayıcı komut dosyası bulunduğunu varsayalım :
#!/bin/bash
FOO=bob
some stuff
exec "$@"
Eğer olarak yürütmek durumunda myscript FOO=bar baz
, exec
gibi bir hata verir exec FOO=bar baz
geçersiz.
Bunun yerine, onu myscript env FOO=bar baz
yürütüldüğü gibi adlandırıyorsunuz exec env FOO=bar baz
ve tamamen geçerli.
FOO=bar exec baz
Yine de yapabilirsin , böylece env
son noktanda ihtiyacın yok .
exec
şey olduğunda , şu anki ortamını kullanıyor mu?
sudo FOO=bar baz
ortam değişkenlerini gerek kalmadan da geçebilirsiniz env
.
FOO=bar
senaryoya koymak istersem işe yarar . Her FOO
zaman değilse , bar
kodlamak istemiyorum ve yerine iletmek istiyorum.
exec
gibi evet yapar FOO=bar exec baz
.
Bu özel örnekte, kabuğunuzun POSIX uyumlu bir kabuk olduğu varsayımıyla etkin bir fark yoktur baz
ve kabuğun yerleşik bir kabuk olduğu varsayılabilirdir .
Kabuğunuz POSIX uyumlu bir kabuk değilse , örneğin csh
veya tcsh
sözdizimi
FOO=bar baz
çalışmıyor ve eşdeğer bir kabuk sözdizimi yok. Bu kabuklarda, env
komut, ortam değişkenlerini tek bir komut için geçersiz kılmanın veya enjekte etmenin tek yoludur.
Eğer baz
bir kabuk yerleşiğidir diyelim fc
örneğin, o env
çünkü, aynı sonuçları vermeyecektir env
yeni bir süreç yürütülürken yerine komut kabuk tarafından doğrudan yürütülüyor. Dahası, hiçbir orada fc
o şekilde o kabuk çevre ile etkileşim, çünkü sadece bir kabuk yerleşiği olarak çalıştırılabilir ve böylece edebilir, çalıştırılabilir env
olacak asla böyle bir yerleşiği ile çalışmayı fc
.
Ek olarak, yalnızca belirli bir ortam değişkeni kümesiyle boş bir ortamda bir komutu başlatmanıza izin veren seçeneği env
sunar -i
. Dolayısıyla env
, sterilize edilmiş ortamlarda işlem başlatmak için çok yararlı olabilir, örneğin
env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz
tcsh
yazarım (setenv FOO bar; baz)
.
Zaten söylenmiş olanlara ek olarak
VAR=value cmd args > redirs
Bir kabuk (Bourne / POSIX) özelliği olarak, ilettiğiniz ortam değişkenlerinin adıyla sınırlandırılmışsınızdır cmd
. Geçerli kabuk değişkeni adları olmalı ve kabuğa salt okunur veya özel değişkenler olmamalıdır.
Örneğin, yapamazsınız:
1=foo cmd
Veya
+++=bar cmd
bash
yapmanıza izin vermiyor:
SHELLOPTS=xtrace cmd
Yapabiliyorken:
env 1=foo cmd
env +++=bar cmd
env '=baz' cmd
(bunu yapmak istemesin ya da istemesin). Veya:
env SHELLOPTS=xtrace cmd
(Bazen bunu yapmam gerekiyor).
Not bununla env
hala bir içermeyen bir ortam değişkeni dize geçemez =
(değil ya bunu yapmak ister ki).
Kullanımlarından biri env
, $PATH
Shebang hatlarında çalıştırılabilir dosyaları aramaya izin vermektir (çünkü çalıştırılabilir dosyayı ararken env
dikkate alır $PATH
). Bu, çağırmak istediğiniz yürütülebilir dosya farklı makinelerde farklı yerlerde olabilirse faydalıdır. Örneğin,
#!/usr/bin/env perl
olursa olsun yüklü olup olmadığını Perl ile bu script çalıştırır çalıştırılabilir bit kümesi içeren bir senaryonun ilk satırında /usr/bin/perl
ya da /usr/local/bin/perl
sürece dizin yolu olduğu gibi, ya da tamamen farklı bir yerde.
Elbette, bu yol araması ek bir riskle birlikte gelir, ancak daha sonra, risk açıkça yazdığınızdan daha büyük değildir perl yourscript.pl
, bu da arama yolunda perl'i gösterir.
env
Gerçekten yararlı olduğu bir başka zaman , çevreyi tamamen kontrol etmek istiyorsanız. Ortamını tamamen kontrol etmek istediğim bir sunucu programı çalıştırıyorum (Informix, tahmin edemezseniz). Bir kaç env
değişkeni doğru değerlere ayarlayan bir betiğin sonunda kullanıyorum :
env -i HOME="$IXD" \
INFORMIXDIR="$IXD" \
INFORMIXSERVER="$IXS" \
${IXC:+INFORMIXCONCSMCFG="$IXC"} \
${IXH:+INFORMIXSQLHOSTS="$IXH"} \
IFX_LISTEN_TIMEOUT=3 \
ONCONFIG="onconfig.$IXS" \
PATH="/bin:/usr/bin:$IXD/bin" \
SHELL=/bin/ksh \
TZ=UTC0 \
$ONINIT "$@"
-i
Seçenek mevcut ortamı zaps. Sonraki VAR=value
seçenekler ayarlamak istediğim ortam değişkenlerini belirler; Programın ismi $ONINIT
girilmiş olup herhangi bir komut satırı argümanı ile birlikte yazılmıştır "$@"
.
${IXH:+INFORMIXSQLHOSTS="$IXH"}
Yapı, sadece geçer INFORMIXSQLHOSTS="$IXH"
için env
ise $IXH
boş olmayan bir değere ayarlanır.