Sudo kullanırken ortam değişkenleri nasıl tutulur


425

Sudo ile herhangi bir komut kullandığımda ortam değişkenleri orada değil. Örneğin HTTP_PROXY ayarlandıktan sonra komut wgetolmadan sorunsuz çalışır sudo. Ancak yazdığımda sudo wgetproxy ayarını atlayamayacağını söylüyor.



Yanıtlar:


475

Öncelikle ihtiyacınız var export HTTP_PROXY. İkincisi, man sudodikkatlice okumalısınız ve -Ebayrağa dikkat etmelisiniz . Bu çalışıyor:

$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'

Adam sayfasından alıntı:

-E, --preserve-env
             Indicates to the security policy that the user wishes to preserve their
             existing environment variables.  The security policy may return an error
             if the user does not have permission to preserve the environment.

1
büyük bazı yapılandırma dosyaları değiştirmek için tek sorun, örneğin kemer için pacman -E yapmak için geçti
Ahmed Aswani

7
Wget için -E'ye (çevreyi koru) izin vermek için sudo kuralında wget'in çalışmasına izin veren SETENV etiketini belirtmeniz gerekir - Örnek: <kullanıcıadı> ALL = (kök) NOPASSWD: SETENV: <wget yolu>
John Bowers

66
Değişken PATH veya PYTHONPATH ise bu "-E" çalışmaz.
16:16

Ayrıca herhangi bir LC_*değişkenle çalışmaz . Bu yüzden sadece yapın export LOL_FOO=$LC_FOOve kullanın LOL_FOO.
luckydonald

9
Bu PATH, .bashrcdosyadaki öğeye bir öğe eklemek gibi daha basit bir durumla çalışmadı - örneğin export PATH=myPath:$PATH,. Ben yazarsanız sudo -E bash -c 'echo $PATH', o zaman PATHçünkü muhtemelen MyPath içermiyor sudozaten yerel değerini devre dışı bıraktı PATHçağırmadan önce bash. Aksine, aşağıdaki cevabı stackoverflow.com/a/33183620/5459638 etkili buldum , yanisudo PATH=$PATH command
XavierStuvw

310

İşin püf noktası, komut sudoersaracılığıyla dosyaya ortam değişkenleri sudo visudoeklemek ve şu satırları eklemektir:

Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"

ArchLinux wiki'den alınmıştır .

Ubuntu 14 için, çok değişkenli hatların hatalarını döndürdüğü için ayrı satırlar belirtmeniz gerekir:

Defaults  env_keep += "http_proxy"
Defaults  env_keep += "https_proxy"
Defaults  env_keep += "HTTP_PROXY"
Defaults  env_keep += "HTTPS_PROXY"

11
Bu, bilgi sızıntısını ve güvenlik deliklerini önlemek için tartışmasız en iyi seçenektir. sudo -EBir kerelik için aynı etkiyi elde etmenin kesin ateş yolu
55'te

Ben sudo (jhbuild) çağıran bir süreç sorunla karşılaştı ve sudo -E bayrağı geçmek için söyleyemeyiz, bu yüzden bu benim çözümdür.
jgomo3

61
Eğer gerektiği Bildirimi asla düzenleme etc/sudoersdoğrudan. Bunun yerine, dosyanın visudoüzerine yazmadan önce düzenlemelerinizin sözdizimini kontrol eden komutu kullanın sudoers. Bu şekilde, düzenleme sırasında hata yaparsanız kendinizi kilitlemezsiniz.
Henning

1
Büyük harfli env vars kullanmayı düşünün. Benim durumumda HTTP_PROXY ve HTTPS_PROXY kullanımı işe yaradı.
pabo

2
küçük harf varyantı hem wget hem de curl'da çalıştığım için deneyimimden daha iyi.
Miroslav Mocek

57

Tek seferlik kullanılabilir olmasını istediğiniz bağımsız değişkenler için onu komutun bir parçası haline getirebilirsiniz.

sudo http_proxy=$http_proxy wget "http://stackoverflow.com"

Ben bu cevabı test ettik packageeklenen bazı MyPath altında PATHyer .bashrc(kayıtlarında exportclausule). Sonra sudo PATH=$PATH which packageaksine, doğru cevabı bulur sudo which package. Ancak, sudo PATH=$PATH packagedaha ileri gitmez sudo package(dosya bulunamadı). Öte yandan, packageile çağrılan bir kabuktan bir ova fırlatılması sudo bashuzatılmış yolu korur ve packagesudo hakları verir (bir taşlı iki güvercin). Yanıt gerçekten hangi komutları başlattığınıza bağlıdır
XavierStuvw

2
Sudo için PATH çözünürlüğü başka bir konudur - herkes bu konuyu bulmak için bu yazı bulmak gerekir unix.stackexchange.com/questions/83191/…
buckaroo1177125

24

Ayrıca env_keepAhmed Aswani'nin cevabındaki iki ifadeyi şöyle tek bir ifadede birleştirebilirsiniz:

Defaults env_keep += "http_proxy https_proxy"

Ayrıca env_keepyalnızca böyle bir komut belirtmeyi de düşünmelisiniz :

Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"


1

Basit bir sarma işlevi (veya döngü için sıralı)

Benzersiz bir çözüm buldum çünkü:

  • sudo -E "$@" komutum için sorun yaratan değişkenler sızdırıyordu
  • sudo VAR1="$VAR1" ... VAR42="$VAR42" "$@" benim durumumda uzun ve çirkindi

demo.sh

#!/bin/bash

function sudo_exports(){
    eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) "$@"
}

# create a test script to call as sudo
echo 'echo Forty-Two is $VAR42' > sudo_test.sh
chmod +x sudo_test.sh

export VAR42="The Answer to the Ultimate Question of Life, The Universe, and Everything."

export _EXPORTS="_EXPORTS VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 VAR7 VAR8 VAR9 VAR10 VAR11 VAR12 VAR13 VAR14 VAR15 VAR16 VAR17 VAR18 VAR19 VAR20 VAR21 VAR22 VAR23 VAR24 VAR25 VAR26 VAR27 VAR28 VAR29 VAR30 VAR31 VAR32 VAR33 VAR34 VAR35 VAR36 VAR37 VAR38 VAR39 VAR40 VAR41 VAR42"

# clean function style
sudo_exports ./sudo_test.sh

# or just use the content of the function
eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) ./sudo_test.sh

Sonuç

$ ./demo.sh
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.

Nasıl?

Bu, bash yerleşiminin bir özelliği ile mümkün olur printf. %qBir kabuk alıntı dize üretir. Bash 4.4'teki parametre genişletmesinin aksine , bu, <4.0 bash sürümlerinde çalışır


0

Ortam değişkenlerini bir komut dosyasında tutmanız gerekiyorsa, komutunuzu buradaki bir belgeye koyabilirsiniz. Özellikle bir şeyleri ayarlamak için çok değişkeniniz varsa bu şekilde düzenli görünün.

# prepare a script e.g. for running maven
runmaven=/tmp/runmaven$$
# create the script with a here document 
cat << EOF > $runmaven
#!/bin/bash
# run the maven clean with environment variables set
export ANT_HOME=/usr/share/ant
export MAKEFLAGS=-j4
mvn clean install
EOF
# make the script executable
chmod +x $runmaven
# run it
sudo $runmaven
# remove it or comment out to keep
rm $runmaven
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.