【发布时间】:2020-09-02 15:39:18
【问题描述】:
我想制作一个脚本,允许我执行从任何 PID 继承环境变量的命令。 这是我制作的脚本:
#!/bin/sh
VARS=$(cat -A /proc/1/environ | tr "^@" "\n")
COMMAND=""
# sh compatible loop on a variable containing multiple lines
printf %s "$VARS" | while IFS='\n' read -r var
do
if [ "$var" != "" ]; then
export "$var"
fi
done
exec "$@"
虽然导出的变量可用于子进程(由exec 创建),但显然情况并非如此,因为sh my_script.sh printenv 不显示/proc/1/environ 中的环境变量。
我还尝试了以下脚本:
#!/bin/sh
VARS=$(cat -A /proc/1/environ | tr "^@" "\n")
COMMAND=""
# sh compatible loop on a variable containing multiple lines
printf %s "$VARS" | while IFS='\n' read -r var
do
if [ "$var" != "" ]; then
# Replace 'VAR=var' by 'VAR="var"' for eval
# sed replace only the first occurence of the '=' due of the missing /g parameter
escaped=$(echo $var | sed -e 's/=/="/')\"
COMMAND="${COMMAND} ${escaped}"
fi
done
COMMAND="${COMMAND} $@"
eval $COMMAND
但是,即使评估的命令看起来像 VAR=value my_command,eval 似乎也不会导出变量。
我应该如何满足我的需求?
提前致谢
【问题讨论】:
-
替换 NUL 字符我想你想要
tr "\0" "\n" -
管道连接到您的
while read循环是问题所在。见BashFAQ #42。 -
@CharlesDuffy 我尝试使用命名管道(根据 BashFAQ 中兼容的解决方法 POSIX),但我仍然看不到我的环境变量。我的新代码是:
bash #!/bin/sh VARS=$(cat /proc/1/environ | tr "\n" " " | tr "\0" "\n") mkfifo mypipe echo "$VARS" > mypipe & # sh compatible loop on a variable containing multiple lines while IFS='\n' read -r var do if [ "$var" != "" ]; then export "$var" fi done < mypipe rm mypipe exec "$@" -
一方面,
IFS='\n'设置了两个分隔符,反斜杠和n;它没有设置换行文字。不过,老实说,如果你只有sh,我会用完全不同的语言——C、Go、Python 等——而不是构建一个无法正确处理所有环境变量的有缺陷的版本。 -
也就是说,等我喝完咖啡坐在电脑前,我会回来仔细看看。