简体   繁体   English

从bash脚本生成bash脚本

[英]Generating a bash script from a bash script

I need to generate a script from within a script but am having problems because some of the commands going into the new script are being interpreted rather than written to the new file. 我需要从脚本中生成一个脚本但是遇到问题,因为正在解释进入新脚本的一些命令而不是写入新文件。 For example i want to create a file called start.sh in it I want to set a variable to the current IP address: 例如,我想在其中创建一个名为start.sh的文件,我想将变量设置为当前的IP地址:

echo "localip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')" > /start.sh

what gets written to the file is: 写入文件的内容是:

localip=192.168.1.78

But what i wanted was the following text in the new file: 但我想要的是新文件中的以下文字:

localip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')"

so that the IP is determined when the generated script is run. 以便在运行生成的脚本时确定IP。

What am i doing wrong ? 我究竟做错了什么 ?

You're making this unnecessary hard. 你这不必要了。 Use a heredoc with a quoted sigil to pass literal contents through without any kind of expansion: 使用带有引号的heredoc来传递文字内容,而不进行任何扩展:

cat >/start.sh <<'EOF'
localip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/')
EOF

Using <<'EOF' or <<\\EOF , as opposed to just <<EOF , is essential; 使用<<'EOF'<<\\EOF ,而不仅仅是<<EOF ,是必不可少的; the latter will perform expansion just as your original code does. 后者将像原始代码一样执行扩展。


If anything you're writing to start.sh needs to be based on current variables, by the way, be sure to use printf %q to safely escape their contents. 如果您要写入start.sh任何内容需要基于当前变量,顺便说一下,请务必使用printf %q来安全地转义其内容。 For instance, to set your current $1 , $2 , etc. to be active during start.sh execution: 例如,要将当前的$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>&-

This is far more efficient than using >>/start.sh on every line that needs to append: Using exec 3>file and then >&3 only opens the file once, rather than opening it once per command that generates output. 这比在需要追加的每一行上使用>>/start.sh更有效:使用exec 3>file然后>&3只打开文件一次,而不是每生成一次输出的命令打开一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM