我需要从脚本中生成脚本,但遇到了问题,因为一些进入新脚本的命令被解释而不是写入新文件。例如,我想在其中创建一个名为 start.sh 的文件,我想为当前 IP 地址设置一个变量:
echo "localip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')" > /start.sh
写入文件的内容是:
localip=192.168.1.78
但我想要的是新文件中的以下文本:
localip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')"
以便在运行生成的脚本时确定 IP。
我做错了什么?
最佳答案
你正在使这个不必要的困难。使用带引号的 heredoc 来传递文字内容而不进行任何扩展:
cat >/start.sh <<'EOF'
localip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
EOF
使用 <<'EOF'
或 <<\EOF
,而不仅仅是 <<EOF
, 是必不可少的;后者将像您的原始代码一样执行扩展。
如果您要写信给 start.sh
需要根据当前变量,对了,一定要用printf %q
安全地逃脱他们的内容。例如,设置您当前的 $1
, $2
等在 start.sh
期间处于事件状态执行:
# open start.sh for output on FD 3
exec 3>/start.sh
# build a shell-escaped version of your argument list
printf -v argv_str '%q ' "$@"
# add to the file we previously opened a command to set the current arguments to that list
printf 'set -- %s\n' "$argv_str" >&3
# pass another variable through safely, just to be sure we demonstrate how:
printf 'foo=%q\n' "$foo" >&3
# ...go ahead and add your other contents...
cat >&3 <<'EOF'
# ...put constant parts of start.sh here, which can use $1, $2, etc.
EOF
# close the file
exec 3>&-
这比使用 >>/start.sh
效率要高得多在需要追加的每一行:使用 exec 3>file
然后 >&3
只打开文件一次,而不是每个生成输出的命令都打开一次。
关于linux - 从 bash 脚本生成 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32077318/