如何 cat <<EOF >> 包含代码的文件?
Posted
技术标签:
【中文标题】如何 cat <<EOF >> 包含代码的文件?【英文标题】:How to cat <<EOF >> a file containing code? 【发布时间】:2014-05-07 00:30:17 【问题描述】:我想使用cat <<EOF >>
将代码打印到文件中:
cat <<EOF >> brightup.sh
!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi
EOF
但是当我检查文件输出时,我得到了这个:
!/bin/bash
curr=1634
if [ -lt 4477 ]; then
curr=406;
echo > /sys/class/backlight/intel_backlight/brightness;
fi
我尝试使用单引号,但输出也带有单引号。我怎样才能避免这个问题?
【问题讨论】:
你也应该修复shebang。第一行必须是字面上的#!/bin/bash
,没有别的——#!
是使它成为有效的 shebang 行的原因,之后是解释器的路径。
顺便说一句,进程替换的现代语法是$(command)
,而不是`command`
。为了获取文件的内容,Bash 有$(<file)
【参考方案1】:
您只需要很小的改动;在<<
之后单引号引用此处的文档分隔符。
cat <<'EOF' >> brightup.sh
或等效的反斜杠转义它:
cat <<\EOF >>brightup.sh
如果没有引用,这里的文档将像您发现的那样进行变量替换,反引号将被评估等等。
如果您需要扩展一些(但不是全部)值,则需要单独转义要阻止的值。
cat <<EOF >>brightup.sh
#!/bin/sh
# Created on $(date # : <<-- this will be evaluated before cat;)
echo "\$HOME will not be evaluated because it is backslash-escaped"
EOF
会产生
#!/bin/sh
# Created on Fri Feb 16 11:00:18 UTC 2018
echo "$HOME will not be evaluated because it is backslash-escaped"
根据@fedorqui 的建议,这里是来自man bash
的相关部分:
这里的文档
这种类型的重定向指示 shell 从 当前源,直到仅包含分隔符的行(没有 尾随空白)可见。到目前为止读取的所有行都是 然后用作命令的标准输入。
here-documents的格式为:
<<[-]word here-document delimiter
没有参数扩展,命令替换,算术扩展, 或对 word 执行路径名扩展。如果单词中有任何字符 被引用,分隔符是单词上引号删除的结果,并且 here-document 中的行没有展开。 如果单词是 未引用,此处文档的所有行都受参数 扩展、命令替换和算术扩展。在里面 后一种情况,字符序列
\<newline>
被忽略,\
必须用于引用字符\
、$
和`
。
【讨论】:
我看到您将 How to avoid heredoc expanding variables? 标记为此邮件的副本。没有异议,只是我会包括 Bash 文档参考,就像我在我的一样(只有 13k 次访问得到了近 100 个代表,所以它似乎很有帮助)。 @fedorqui 也许您实际上想移植您对这个问题的答案?或者我们可以将重复标记切换为相反的方式;我只看题目分数,没看答案分数。 嗯,merging 他们呢,把这个作为目标问题?重复的问题有一个很好的标题,只是它太长了。然而,不知何故,它最近引起了很多关注(我收到了some upvotes per month)。 @fedorqui 我喜欢合并的概念,但我从未见过它在实践中发生;如果我正确理解了情况,模组根本无法处理非平凡的合并,因为麻烦和复杂性远远超过了好处。我所做的一两次是删除一个有用且被赞成的答案,然后在另一个问题下重新发布,尽管我几乎不推荐这种解决方法。 很难说什么时候值得去做。我已经在一个我修改过的网站上完成了它,当时发布了一个好问题,却没有注意到之前还有另一个好问题,两者都有很好的答案。删除我 90 分以上的答案似乎不是一个好计划,因为它会使该问题成为孤儿。【参考方案2】:或者,使用您的 EOF 标记,您需要引用初始标记,因此不会进行扩展:
#-----v---v------
cat <<'EOF' >> brightup.sh
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi
EOF
IHTH
【讨论】:
我会编辑您的帖子,但为了安全起见,不应该是 #!/bin/bash 而不是 !/bin/bash? @MatthewHoggan:是的,你说得对!谢谢你抓住那个。我现在正在修复它。【参考方案3】:这应该可以工作,我刚刚对其进行了测试,它按预期工作:没有发生扩展、替换或你有什么。
cat <<< '
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi' > file # use overwrite mode so that you don't keep on appending the same script to that file over and over again, unless that's what you want.
使用以下方法也可以。
cat <<< ' > file
... code ...'
另外,值得注意的是,在使用heredocs时,例如<< EOF
,会发生替换和变量扩展等。所以做这样的事情:
cat << EOF > file
cd "$HOME"
echo "$PWD" # echo the current path
EOF
将始终导致变量$HOME
和$PWD
的扩展。所以如果你的主目录是/home/foobar
,当前路径是/home/foobar/bin
,file
将如下所示:
cd "/home/foobar"
echo "/home/foobar/bin"
而不是预期的:
cd "$HOME"
echo "$PWD"
【讨论】:
单引号中的here字符串显然不能包含任何单引号,这可能是一个令人望而却步的问题。如果您的脚本需要同时包含单引号和双引号,那么这里的文档是唯一合理的解决方法,尽管 OP 的简单示例当然不是这种情况。此外,切向地,这里的字符串<<<
仅从 Bash 3 开始可用,并且不能移植到其他 shell。
<<<
也可以在 Zsh 中使用
今天我了解到,您可以在打开 heredoc 之后立即使用文件名。谢谢@AlexejMagura!【参考方案4】:
我知道这是一个两年前的问题,但对于那些寻找“如何做”的人来说,这是一个快速的答案。
如果您不想在任何内容周围加上引号,您只需将一段文本写入文件,然后转义要导出为文本的变量(例如用于脚本中)而不转义一个您想导出为变量的值。
#!/bin/bash
FILE_NAME="test.txt"
VAR_EXAMPLE="\"string\""
cat > $FILE_NAME << EOF
\$VAR_EXAMPLE=$VAR_EXAMPLE in $FILE_NAME
EOF
将 "$VAR_EXAMPLE="string" in test.txt" 写入 test.txt
这也可以用于通过省略文件名以相同的规则将文本块输出到控制台
#!/bin/bash
VAR_EXAMPLE="\"string\""
cat << EOF
\$VAR_EXAMPLE=$VAR_EXAMPLE to console
EOF
将“$VAR_EXAMPLE="string" to console”输出到控制台
【讨论】:
【参考方案5】:带有<<EOF>>
的cat 将创建内容或将内容附加到现有文件,不会覆盖。而 <<EOF>
的 cat 将创建或覆盖内容。
cat test.txt
hello
cat <<EOF>> test.txt
> hi
> EOF
cat test.txt
hello
hi
cat <<EOF> test.txt
> haiiiii
> EOF
cat test.txt
haiiiii
【讨论】:
不回答问题以上是关于如何 cat <<EOF >> 包含代码的文件?的主要内容,如果未能解决你的问题,请参考以下文章