从bash脚本生成bash脚本

时间:2015-08-18 16:02:46

标签: linux bash shell

我需要从脚本中生成脚本但是遇到问题,因为正在解释进入新脚本的一些命令而不是写入新文件。例如,我想在其中创建一个名为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。

我做错了什么?

1 个答案:

答案 0 :(得分:7)

你正在努力做到这一点。使用带有引号的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只打开文件一次,而不是每个命令打开一次生成输出。