Kısmak ya da kapmamak


32

Komut arasındaki fark nedir

$ env FOO=bar baz

ve

$ FOO=bar baz

Ne etkisi envvar?


4
Bir yan soruyu sıralayın, ancak böyle bir tek alt komut için bir ortam değişkeni ayarladığınızda, bu özelliğin kendisi ne denir? Bu konuda bilgi bulmak için her zaman zor zamanlar yaşadım çünkü ne dendiğini bilmiyorum.
John Cromartie

1
@ JohnCromartie, bunu bir soru olarak sormalısınız.
cjm

1
Bash için, burada belgelenmiştir: gnu.org/software/bash/manual/…
glenn jackman

2
@JohnCromartie Her kabuk komutunun isteğe bağlı bir bileşenidir, bu nedenle çoğu kabuk kılavuzunun "Basit Komutlar" bölümündedir. POSIX için bu burada olurdu . glenn zaten analog olan bölümleri bash el kitabından bağladı.
jw013

Atama yoluyla var olmayan bir değişkeni ayarlamak bir kabuk değişkeni yaratır. ENV ile ayarlamak veya değişkeni dışa aktarmak, değişkeni kabuğun yürütme ortamına iter. Var olan bir değişkenin değerini değiştirmek, eğer varsa, yürütme ortamı değerini günceller, aksi takdirde kabuk iç değişkenlerinde değiştirin.
Johan

Yanıtlar:


26

İşlevsel olarak eşdeğerdirler.

Ana fark, env FOO=bar bazkabuk bazile FOO=bar bazkabuğ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 baztercih 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 execkendisine 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, execgibi bir hata verir exec FOO=bar bazgeçersiz.
Bunun yerine, onu myscript env FOO=bar bazyürütüldüğü gibi adlandırıyorsunuz exec env FOO=bar bazve tamamen geçerli.


1
FOO=bar exec bazYine de yapabilirsin , böylece envson noktanda ihtiyacın yok .
Stéphane Chazelas 15:14

Bir execşey olduğunda , şu anki ortamını kullanıyor mu?
glenn jackman,

1
Aynen @StephaneChazelas ve sudo FOO=bar bazortam değişkenlerini gerek kalmadan da geçebilirsiniz env.
Mike Miller

1
@StephaneChazelas, sadece FOO=barsenaryoya koymak istersem işe yarar . Her FOOzaman değilse , barkodlamak istemiyorum ve yerine iletmek istiyorum.
Patrick

@glennjackman evet, değişkenler dışa aktarıldığında veya aktarılmadan önce olduğu execgibi evet yapar FOO=bar exec baz.
Patrick

14

Bu özel örnekte, kabuğunuzun POSIX uyumlu bir kabuk olduğu varsayımıyla etkin bir fark yoktur bazve kabuğun yerleşik bir kabuk olduğu varsayılabilirdir .

Kabuğunuz POSIX uyumlu bir kabuk değilse , örneğin cshveya tcshsözdizimi

FOO=bar baz

çalışmıyor ve eşdeğer bir kabuk sözdizimi yok. Bu kabuklarda, envkomut, ortam değişkenlerini tek bir komut için geçersiz kılmanın veya enjekte etmenin tek yoludur.

Eğer bazbir kabuk yerleşiğidir diyelim fcörneğin, o envçünkü, aynı sonuçları vermeyecektir envyeni bir süreç yürütülürken yerine komut kabuk tarafından doğrudan yürütülüyor. Dahası, hiçbir orada fco ş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 envolacak 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 envsunar -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

Eskiden kullandığım zaman eşdeğer işlevi elde etmek için tcshyazarım (setenv FOO bar; baz).
Barmar

6

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 envhala bir içermeyen bir ortam değişkeni dize geçemez =(değil ya bunu yapmak ister ki).


2

Kullanımlarından biri env, $PATHShebang hatlarında çalıştırılabilir dosyaları aramaya izin vermektir (çünkü çalıştırılabilir dosyayı ararken envdikkate 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/perlya da /usr/local/bin/perlsü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.


2

envGerç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ç envdeğ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 "$@"

-iSeçenek mevcut ortamı zaps. Sonraki VAR=valueseçenekler ayarlamak istediğim ortam değişkenlerini belirler; Programın ismi $ONINITgirilmiş 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 envise $IXHboş olmayan bir değere ayarlanır.

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.