我有一个环境变量文件,我在shell脚本中提供,例如:
# This is a comment
ONE=1
TWO=2
THREE=THREE
# End
在我的脚本中,我将此文件(假设它称为“./vars”)导入当前环境,并根据用户输入更改(某些)变量。例如:
#!/bin/sh
# Read variables
source ./vars
# Change a variable
THREE=3
# Write variables back to the file??
awk 'BEGIN{FS="="}{print $1=$$1}' <./vars >./vars
正如你所看到的,我一直在尝试使用awk来编写变量,sed也是如此。没有成功。脚本的最后一行失败。有没有办法用awk或sed做到这一点(最好是保留注释,甚至带有'='字符的注释)?或者我应该将'read'与字符串切割结合在一个while循环或其他魔法中?如果可能的话,我想避免使用perl / python并使用Busybox中提供的工具。非常感谢。
编辑:也许用例可能会清楚我的问题是什么。我保留了一个由shell环境变量声明组成的配置文件:
# File: network.config
NETWORK_TYPE=wired
NETWORK_ADDRESS_RESOLUTION=dhcp
NETWORK_ADDRESS=
NETWORK_ADDRESS_MASK=
我还有一个名为'setup-network.sh'的脚本:
#!/bin/sh
# File: setup-network.sh
# Read configuration
source network.config
# Setup network
NETWORK_DEVICE=none
if [ "$NETWORK_TYPE" == "wired" ]; then
NETWORK_DEVICE=eth0
fi
if [ "$NETWORK_TYPE" == "wireless" ]; then
NETWORK_DEVICE=wlan0
fi
ifconfig -i $NETWORK_DEVICE ...etc
我还有一个名为'configure-network.sh'的脚本:
#!/bin/sh
# File: configure-network.sh
# Read configuration
source network.config
echo "Enter the network connection type:"
echo " 1. Wired network"
echo " 2. Wireless network"
read -p "Type:" -n1 TYPE
if [ "$TYPE" == "1" ]; then
# Update environment variable
NETWORK_TYPE=wired
elif [ "$TYPE" == "2" ]; then
# Update environment variable
NETWORK_TYPE=wireless
fi
# Rewrite configuration file, substituting the updated value
# of NETWORK_TYPE (and any other updated variables already existing
# in the network.config file), so that later invocations of
# 'setup-network.sh' read the updated configuration.
# TODO
如何重写配置文件,仅更新配置文件中已存在的变量,最好是保留注释和空行?希望这能把事情搞清楚一点。再次感谢。
答案 0 :(得分:1)
你不能使用awk并从同一个文件读取和写入(是问题的一部分)。
我更喜欢在重写之前重命名文件(但你可以保存到tmp然后重命名)。
/bin/mv file file.tmp
awk '.... code ...' file.tmp > file
如果你的env文件越来越大,你会发现你的操作系统的缓冲区大小被截断了。
另外,不要忘记gawk(大多数Linux安装中的std)都有内置数组ENVIRON。你可以从那里创建你想要的东西
awk 'END {
for (key in ENVIRON) {
print key "=" ENVIRON[key]
}
}' /dev/null
当然,您可以获得环境中的所有内容,因此可能比您想要的更多。但可能是一个更好的地方,从你想要完成的事情开始。
修改强> 最具体的是
awk -F"=" '{
if ($1 in ENVIRON) {
printf("%s=%s\n", $1, ENVIRON[$1])
}
# else line not printed or add code to meet your situation
}' file > file.tmp
/bin/mv file.tmp file
编辑2
我认为你的var =值可能需要export
-ed所以它们对于awk ENVIRON数组是可见的。
和
echo PATH=xxx| awk -F= '{print ENVIRON[$1]}'
打印PATH的现有值。
我希望这会有所帮助。
P.S。因为您似乎是新用户,如果您得到的答案可以帮助您,请记住将其标记为已接受,并且/或者给它一个+(或 - )作为有用的答案。
答案 1 :(得分:0)
我不知道你要做什么,但是如果你想改变变量THREE的值,
awk -F"=" -vt="$THREE" '$1=="THREE" {$2=t}{print $0>FILENAME}' OFS="=" vars
答案 2 :(得分:0)
您可以使用bash执行此操作:
rewrite_config() {
local filename="$1"
local tmp=$(mktemp)
# if you want the header
echo "# File: $filename" >> "$tmp"
while IFS='=' read var value; do
declare -p $var | cut -d ' ' -f 3-
done < "$filename" >> "$tmp"
mv "$tmp" "$filename"
}
像
一样使用它source network.config
# manipulate the variables
rewrite_config network.config
我使用临时文件来尽可能长时间地保持配置文件的存在。