从bash脚本生成一个bash脚本

我需要从脚本内部生成脚本,但遇到问题,因为进入新脚本的一些命令正在被解释而不是写入新文件。 例如,我想创build一个名为start.sh的文件,我想设置一个variables到当前的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。

我究竟做错了什么 ?

你让这不必要的困难。 使用引用sigil的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只打开一次文件,而不是在每个生成输出的命令中打开一次。