deploy.sh
USERNAME="Tom"
PASSWORD="abc123"
FILE="config.conf"
sed -i "s/\PLACEHOLDER_USERNAME/$USERNAME/g" $FILE
sed -i "s/\PLACEHOLDER_PASSWORD/$PASSWORD/g" $FILE
配置文件
deloy="PLACEHOLDER_USERNAME"
pass="PLACEHOLDER_PASSWORD"
此文件将我在部署中定义的变量放入我的配置文件中。我无法获取该文件,所以我想以这种方式放置我的变量。
问题
我想要一个通用的命令,用于使用某种 while 循环而不是每个变量一个命令来处理所有占位符变量。这意味着文件中以 placeholder_ 开头的任何术语都将尝试替换为已在 deploy.sh 中定义的变量的值
所有变量都应设置且不能为空。我想如果它找不到合适的变量,是否有能力打印警告,但这不是强制性的。
请您参考如下方法:
基本上,使用 shell 代码编写一个 sed 脚本,然后使用 sed -i .bak -f sed.script config.conf 来应用它:
trap "rm -f sed.script; exit 1" 0 1 2 3 13 15
for var in USERNAME PASSWORD
do
echo "s/PLACEHOLDER_$var/${!var}/"
done > sed.script
sed -i .bak -f sed.script config.conf
rm -f sed.script
trap 0
这里的主要“技巧”是:
- 知道
${!var}扩展为$var命名的变量的值,并且 - 知道
sed将通过-f sed.script获取一个充满命令的脚本,并且 - 知道如何使用
trap来确保清理临时文件。
你也可以使用 sed -e "s/.../.../"-e "s/.../.../"-i .bak config.conf也一样,但我认为脚本文件更容易,尤其是当您有两个以上的值要替换时。如果您想走这条路,请使用 bash 数组来保存 sed 的参数。更仔细的脚本会在脚本文件名中至少使用 $$,或者使用 mktemp 来创建临时文件。
修改后的答案
The trouble is, although much closer to being generic, it is still not generic since I have to manually put in what variables I want to change. Can it not be more like "for each placeholder_, find the variable in
deploy.shand add that variable, so it can work for any number of variables.
因此,找到配置文件中的变量是什么,然后应用上一个答案的技术来解决该问题:
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
for file in "$@"
do
for var in $(sed 's/.*PLACEHOLDER_\([A-Z0-9_]*\).*/\1/' "$file")
do
value="${!var}"
[ -z "$value" ] && { echo "$0: variable $var not set for $file" >&2; exit 1; }
echo "s/PLACEHOLDER_$var/$value/"
done > $tmp
sed -i .bak -f $tmp "$file"
rm -f $tmp
done
trap 0
此代码仍然从环境中提取值。如果你想从 shell 脚本中提取设置,你需要弄清楚需要什么,但这是可以做到的——脚本必须有足够的 self 意识才能找到它的来源,这样它就可以搜索名称。但是基础知识在这个答案中;剩下的就是修补问题,直到它满足您的需要。
