我创建了一个bash脚本,该脚本可以在/ etc / environment中追加或覆盖一些现有的环境变量。脚本如下所示:
#!/bin/bash
declare -a array=("http_proxy=http://username:password@proxy:8080"
"https_proxy=http://username:password@proxy:8080"
"ftp_proxy=ftp://username:password@proxy:8080"
"no_proxy=\"localhost, 127.0.0.1\""
)
for i in "${array[@]}"; do
awk -v var="${i%%=*}" '$0 !~ var' /etc/environment > /etc/environment
echo "$i" >> /etc/environment
done
给出以下输入(/ etc / environment):
http_proxy=http://otheruser:password@otherproxy:8080
https_proxy=http://username:password@proxy:8080
some_env_varible=some_value
我期望以下输出:
http_proxy=http://username:password@proxy:8080
https_proxy=http://username:password@proxy:8080
ftp_proxy=ftp://username:password@proxy:8080
no_proxy="localhost, 127.0.0.1"
some_env_variable=some_value
但是我得到以下输出:
http_proxy=http://username:password@proxy:8080
https_proxy=http://username:password@proxy:8080
ftp_proxy=ftp://username:password@proxy:8080
no_proxy="localhost, 127.0.0.1"
在脚本外部运行awk命令似乎可以正常工作,仅返回与特定环境变量不匹配的行。我很困惑为什么这个脚本无法正常工作。
根据请求:
$ sudo cat /etc/environment
http_proxy=http://username:password@proxy:8080
https_proxy=http://username:password@proxy:8080
ftp_proxy=ftp://username:password@proxy:8080
no_proxy="localhost, 127.0.0.1"
$ i="http_proxy=http://username2:password2@proxy:8080"
$ sudo awk -v var="${i%%=*}" '$0 !~ var' /etc/environment
https_proxy=http://username:password@proxy:8080
ftp_proxy=ftp://username:password@proxy:8080
no_proxy="localhost, 127.0.0.1"
答案 0 :(得分:4)
您想要实现的目标看起来有些麻烦,您可能需要考虑以下任何一种选择:
更新原始脚本:
您编写的awk行尝试打印文件/etc/environment
中没有的所有内容。这正是grep -v
所做的:
for i in "${array[@]}"; do
grep -v "${i%%=*}" /etc/environment > /etc/environment.new
echo "$i" >> /etc/environment.new
mv /etc/environment.new /etc/environment
done
利用grep
的力量:
现在我们使用grep
,您应该知道该标志
-f FILE, --file=FILE
从FILE
获取模式,每行一个。空文件包含零个模式,因此不匹配任何内容。
因此,利用流程替换(<(command)
),您现在可以执行以下操作:
grep -v -f <(printf "%s\n" "${array[@]}" | cut -d= -f1) -F /etc/environment > /etc/environment.new
printf "%s\n" "${array[@]}" >> /etc/environment.new
mv /etc/environment.new /etc/environment
在这里,我们使用printf "%s\n" "${array[@]}"
在新行(cfr bash print array elements on separate lines)上打印数组,并使用cut
命令检索=
之前的所有内容。
只需使用一个awk
:
当您想到grep
,cut
,awk
,sed
,tr
的组合时,...通常可以将其替换为一个awk
。我们将使用awk
来读取2个文件。第一个是/etc/environment
,第二个是我们可以从printf
命令生成的文件。我们将使用aawk数组,其中存储每个key
的值,其中key
是=
之前的部分。因此=
符号将成为我们的定界符。此外,如果遇到具有相同键的变量,它将被覆盖。这使我们可以用新值更新值。
awk -F'=' '{a[$1]=$0}END{for(i in a) print a[i] }' /etc/environment <(printf "%s\n" "${array[@]}")
如果您在脚本中没有真正使用数组,则可以使用HERE文档来实现相同的目的:
cat - <<EOF awk -F'=' '{a[$1]=$0}END{for(i in a) print a[i] }' /etc/environment -
http_proxy=http://username:password@proxy:8080
https_proxy=http://username:password@proxy:8080
ftp_proxy=ftp://username:password@proxy:8080
no_proxy="localhost, 127.0.0.1"
EOF