我正在寻找一种简单的方法将多行脚本内联到文档中,以使每个步骤的作用变得透明。
这有效
echo "echo 1234" | bash
这也是
echo 'for N in 1 2 3; do echo $N; done' | bash
不过,我想使用这样的东西(但它不起作用):
echo <<EOF | bash
for N in 1 2 3; do
echo "N is ${N}"
done
EOF
更新,迄今为止最接近的有效解决方案是:
cat <<EOF|bash
for N in 1 2 3 4; do
echo "N is now \$N"
done
EOF
但理想情况下,我不希望逃离\$N
正确的解决方案不会:
- 使用未安装的工具默认 Debian 配置
- 涉及临时文件
- 下载脚本(
curl -o - htpp://blah.com/script | bash
等)
理想情况下,它是读者可以复制粘贴、按下回车键并无需进一步操作即可执行的内容。
答案1
如果引用或转义此处的文档分隔符(即<<'EOF'
或 而<<\EOF
不仅仅是<<EOF
),则 shell 不会对内容进行扩展(变量等)。
cat <<'EOF' | bash
for N in 1 2 3; do
echo "N is ${N}"
done
EOF
顺便说一句,这个cat
命令在这里并没有真正做任何有用的事情(它只是所谓的“无用的 cat” 或 UUoC)。您可以将其消除并直接将输入发送至bash
:
bash <<'EOF'
for N in 1 2 3; do
echo "N is ${N}"
done
EOF
如果代码片段需要读取输入,那就有点棘手了,因为脚本的输入是...脚本片段本身。在大多数类 Unix 操作系统上,您可以通过将脚本传递到不同的文件描述符并告诉bash
“执行”该文件描述符来避免这种情况:
bash /dev/fd/3 3<<'EOF'
read -p "Enter something here: " input
echo "You entered: ${input}"
EOF
但请注意,这些代码片段之一中设置的任何变量(如$input
这里)都仅在该 shell 进程中设置,并且在退出时将会丢失。
答案2
我认为你能做的最好的事情是这样的:
bash -c '
echo "Simple scriptlike thingy"
for I in 1 2 3 45; do
echo "I is now ${I}"
done
'
请注意,这实际上是将 while 脚本作为参数传递给-c
switch,而该参数本身将被解析bash
。这就是为什么你不能使用"
这样的符号:
bash -c "
THING=text
echo this will not work: $THING
"
因为在参数中,$THING
在作为参数传递之前被替换,并且由于THING
未设置,它将被替换为空字符串。用撇号括起来的字符串不会被解析,因此它可用于包含要在“第二个 bash 进程”解析脚本时设置的变量。
对于更复杂的脚本,我认为最好的方法是让读者保存脚本并运行它,但对于简单的构造,上述方法应该有效。