Khi tôi sử dụng bất kỳ lệnh nào với sudo, các biến môi trường không có ở đó. Ví dụ: sau khi đặt HTTP_PROXY, lệnh wget
hoạt động tốt mà không có sudo
. Tuy nhiên nếu tôi gõ sudo wget
thì nó báo không thể bỏ qua cài đặt proxy.
Khi tôi sử dụng bất kỳ lệnh nào với sudo, các biến môi trường không có ở đó. Ví dụ: sau khi đặt HTTP_PROXY, lệnh wget
hoạt động tốt mà không có sudo
. Tuy nhiên nếu tôi gõ sudo wget
thì nó báo không thể bỏ qua cài đặt proxy.
Câu trả lời:
Đầu tiên bạn cần phải export HTTP_PROXY
. Thứ hai, bạn cần đọc man sudo
kỹ, và chú ý đến -E
cờ. Những công việc này:
$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'
Đây là trích dẫn từ trang người đàn ông:
-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_*
biến. Vì vậy, chỉ cần làm export LOL_FOO=$LC_FOO
và sử dụng LOL_FOO
thay thế.
PATH
vào .bashrc
tệp - giả sử , export PATH=myPath:$PATH
. Nếu tôi gõ sudo -E bash -c 'echo $PATH'
, thì PATH
không chứa myPath có lẽ vì sudo
đã vô hiệu hóa giá trị cục bộ PATH
trước khi gọi bash
. Thay vào đó, tôi đã tìm thấy câu trả lời bên dưới stackoverflow.com/a/33183620/5459638 có hiệu lực, đó làsudo PATH=$PATH command
Mẹo nhỏ là thêm các biến môi trường vào sudoers
tệp thông qua sudo visudo
lệnh và thêm các dòng sau:
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
lấy từ wiki ArchLinux .
Đối với Ubuntu 14, bạn cần chỉ định trong các dòng riêng biệt vì nó trả về lỗi cho các dòng đa biến:
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
sudo -E
là cách chắc chắn để adhoc có được hiệu quả tương tự cho một lần, mặc dù vậy
etc/sudoers
trực tiếp. Thay vào đó, hãy sử dụng visudo
lệnh kiểm tra cú pháp của bạn trước khi ghi đè sudoers
tệp. Bằng cách đó, bạn không tự khóa nếu bạn mắc lỗi trong khi chỉnh sửa.
Đối với các biến riêng lẻ bạn muốn cung cấp trên cơ sở một lần, bạn có thể biến nó thành một phần của lệnh.
sudo http_proxy=$http_proxy wget "http://stackoverflow.com"
package
số myPath được thêm vào PATH
trong .bashrc
tệp (với export
mệnh đề). Sau đó sudo PATH=$PATH which package
tìm câu trả lời đúng, không giống như sudo which package
. Tuy nhiên, sudo PATH=$PATH package
không đi xa hơn sudo package
(không tìm thấy tệp). Mặt khác, khởi động một đồng bằng package
từ một chiếc vỏ được gọi với sudo bash
bảo tồn con đường mở rộng và trao package
quyền sudo (hai con chim bồ câu với một viên đá). Vì vậy, phản hồi thực sự phụ thuộc vào lệnh bạn đang khởi chạy
Tôi đã đưa ra một giải pháp độc đáo bởi vì:
sudo -E "$@"
đã rò rỉ các biến gây ra vấn đề cho lệnh của tôisudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
dài và xấu trong trường hợp của tôi#!/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.
Điều này được thực hiện bởi một tính năng của nội dung bash printf
. Việc %q
tạo ra một chuỗi trích dẫn shell. Không giống như mở rộng tham số trong bash 4.4 , điều này hoạt động trong các phiên bản bash <4.0
Nếu bạn có nhu cầu giữ các biến môi trường trong một tập lệnh, bạn có thể đặt lệnh của bạn trong một tài liệu ở đây như thế này. Đặc biệt là nếu bạn có nhiều biến để thiết lập mọi thứ trông gọn gàng theo cách này.
# 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