使用echo / linux创建一个包含多行脚本的输出文件

21
尝试创建一个小脚本,能够将脚本的一部分原封不动地写入输出文件中(保持原样)。
源文件文本。
echo "
yellow=`tput setaf 3`
bel=`tput bel`
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0
echo"#${green}Installing packages${reset}#" &&
" >> output.txt

期望的输出:

yellow=`tput setaf 3`
bel=`tput bel`
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0
echo"#${green}Installing packages${reset}#" &&

我理解的是:

yellow=^[[33m
bel=^G
red=^[[31m
green=^[[32m
reset=^[(B^[[m
echo"#${green}Installing packages${reset}#" &&

使用全新安装的CentOS 7 Minimal版。 寻找一种可应用于整个脚本/文本的解决方案,而非逐行更改,我认为可以使用sed来实现...

4个回答

37

您需要转义反引号(`):

#!/bin/bash
echo "
yellow=\`tput setaf 3\`
bel=\`tput bel\`
red=\`tput setaf 1\`
green=\`tput setaf 2\`
reset=\`tput sgr0\`
" >> output.txt

作为额外的福利:

对于多行代码,我更喜欢使用这种方法:

#!/bin/bash
cat << 'EOF' >> output.txt
yellow=$(tput setaf 3)
bel=$(tput bel)
red=$(tput setaf 1)
green=$(tput setaf 2)
reset=$(tput sgr0)
EOF

谢谢,用正斜杠覆盖引号是有效的,但我接下来有一个550行的脚本,我想echo会做一些微小的(难以追踪的)更改,是否有任何解决方案适用于整个脚本,以确保在写入输出文件时不进行任何更改? - Zaza
我不确定为什么你要这样移动脚本?你可以将脚本存储起来,然后只需使用 cp 命令进行复制。 - Nick
我正在创建一个Nagios安装/配置脚本,在某个阶段,脚本必须创建一个输出文件,将其上传到从/远程服务器并在那里运行。 - Zaza
我已更新here-document以避免通过引用定界符来引用常量,这使得here-document的行为类似于单引号字符串。此外,优先使用$(...)而不是反引号。某种程度上,cat解决方案效率不高,因为它运行一个外部进程,而echo是内置的,但在这种情况下,可读性是付出的微小代价。 - chepner
第一个使用正斜杠的解决方案对我来说并不起作用,因为颜色定义会停止工作。但是使用括号的所有解决方案都可以正常工作,包括echo和cat,以及颜色定义不需要进行修改。我将更新标题,说明我发现的有用解决方案。谢谢。 - Zaza

8

使用单引号来防止扩展:

echo '
yellow=`tput setaf 3`
bel=`tput bel`
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`
' >> output.txt

如果您的文本中包含单引号,则上述内容可能无法正常工作。在这种情况下,使用here doc更安全。例如,如果您插入一行var ='something',则上述内容将会出错。

使用here doc如下:

有关详细信息,请参见双引号和单引号之间的区别.

cat >> output.txt <<'EOF'
yellow=`tput setaf 3`
bel=`tput bel`
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`
var='something'
EOF

我知道它们的区别,但在这种情况下,当我使用单引号时,Bash会执行源文件,这意味着 echo ' 将被完全忽略。 - Zaza
@eadmineadmin:请解释一下导致您出现意外行为的程序流程... - Jahid
它简单地执行文件,忽略了“echo '”语句,而“echo"”却能正常工作,但在复制时会产生不必要的更改,如上所示。 - Zaza
@eadmineadmin:我认为在这种情况下heredoc会更安全。请看我的修改。 - Jahid

2

仅作为一个晚期补充:

echo 'string' >> output 命令简单而且很好用。 但是当与 sudo 结合使用时,可能会出现 '...:权限被拒绝' 的错误。

我最近在使用 sudo echo 'string \n other string \n' > /path/to/file 时遇到了一些小问题。

对我来说最好的解决方法是:
printf "Line1\nLine2\nLine3" | sudo tee --append /path/to/file

这样做可以额外将字符串打印到标准输出中,因此您可以看到写入文件的内容。


0

感谢chepner

我找到的最佳解决方案是:

echo '
yellow=$(tput setaf 3)
bel=$(tput bel)
red=$(tput setaf 1)
green=$(tput setaf 2)
reset=$(tput sgr0)
echo"#${green}Installing packages${reset}#"
' >> output

使用此解决方案,所有文本都会原样输出到输出文件中,颜色定义也可以正常工作而无需修改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接