Sudo ile herhangi bir komut kullandığımda ortam değişkenleri orada değil. Örneğin HTTP_PROXY ayarlandıktan sonra komut wget
olmadan sorunsuz çalışır sudo
. Ancak yazdığımda sudo wget
proxy ayarını atlayamayacağını söylüyor.
Sudo ile herhangi bir komut kullandığımda ortam değişkenleri orada değil. Örneğin HTTP_PROXY ayarlandıktan sonra komut wget
olmadan sorunsuz çalışır sudo
. Ancak yazdığımda sudo wget
proxy ayarını atlayamayacağını söylüyor.
Yanıtlar:
Öncelikle ihtiyacınız var export HTTP_PROXY
. İkincisi, man sudo
dikkatlice okumalısınız ve -E
bayrağ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.
LC_*
değişkenle çalışmaz . Bu yüzden sadece yapın export LOL_FOO=$LC_FOO
ve kullanın LOL_FOO
.
PATH
, .bashrc
dosyadaki öğ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 sudo
zaten 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
İşin püf noktası, komut sudoers
aracılığıyla dosyaya ortam değişkenleri sudo visudo
eklemek 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"
sudo -E
Bir kerelik için aynı etkiyi elde etmenin kesin ateş yolu
etc/sudoers
doğ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.
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"
package
eklenen bazı MyPath altında PATH
yer .bashrc
(kayıtlarında export
clausule). Sonra sudo PATH=$PATH which package
aksine, doğru cevabı bulur sudo which package
. Ancak, sudo PATH=$PATH package
daha ileri gitmez sudo package
(dosya bulunamadı). Öte yandan, package
ile çağrılan bir kabuktan bir ova fırlatılması sudo bash
uzatılmış yolu korur ve package
sudo hakları verir (bir taşlı iki güvercin). Yanıt gerçekten hangi komutları başlattığınıza bağlıdır
Benzersiz bir çözüm buldum çünkü:
sudo -E "$@"
komutum için sorun yaratan değişkenler sızdırıyordusudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
benim durumumda uzun ve çirkindi#!/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
$ ./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.
Bu, bash yerleşiminin bir özelliği ile mümkün olur printf
. %q
Bir kabuk alıntı dize üretir. Bash 4.4'teki parametre genişletmesinin aksine , bu, <4.0 bash sürümlerinde çalışır
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