我想使用
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
我尝试添加单引号,但输出也带有单引号。如何避免这个问题?
您只需要一点点改变;在
<<
之后用单引号引用此处文档分隔符。
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 从 当前源直到仅包含定界符的行(没有 看到尾随空白)。到该点为止读取的所有行都是 然后用作命令的标准输入。
此处文档的格式为:
<<[-]word here-document delimiter
无参数扩展、命令替换、算术扩展、 或对 word 执行路径名扩展。如果word中有任何字符 被引用,分隔符是对单词去除引号的结果,并且 此处文档中的行未展开。 如果单词是 不加引号,此处文档的所有行均受参数影响 扩展、命令替换和算术扩展。在里面 后一种情况,字符序列
被忽略,并且\<newline>
必须用于引用字符\
、\
和$
。`
有关相关问题,另请参阅 https://stackoverflow.com/a/54434993
这应该可行,我刚刚测试了它,它按预期工作:没有扩展、替换或发生了什么。
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"
或者,使用 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
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" 到控制台'
cat 与
<<EOF>>
将创建或追加内容到现有文件,不会覆盖。而带有 <<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
不确定不使用 bash 是否可以算作答案。
python -c 'with open("brightup.sh", "w") as fp: fp.write("""
!/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""")'
或将脚本粘贴到控制台(最后按 Ctrl+d):
python -c 'import sys; fp= open("brightup.sh", "w"); print("paste script:"); fp.write("".join(sys.stdin.readlines())); fp.close()'