如何在bash中打印感叹号?

Dav*_*der 6 unix linux bash scripting

我需要printf一个简单的脚本并将输出重定向到一个文件,但是当我这样做时:

printf "#!/bin/bash\ntouch /tmp/1234567890_$RUN" > /tmp/password-change-script_$RUN.sh
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

bash:!/ bin/bash \ntouch:找不到事件

如果我逃避感叹号:

printf "#\!/bin/bash\ntouch /tmp/1234567890_$RUN" > /tmp/password-change-script_$RUN.sh
Run Code Online (Sandbox Code Playgroud)

然后转义字符仍然存在于文件中.

cat /tmp/password-change-script_$RUN.sh
#\!/bin/bash
touch /tmp/1234567890_111
Run Code Online (Sandbox Code Playgroud)

顺便说一句,在这种特殊情况下,#!/ bin/bash必须在文件中.由于某种原因,执行该脚本的二进制文件将不会读取该文件.

Kei*_*son 11

!字符在双引号字符串中展开,但不在单引号字符串中.

printf '#!/bin/bash\ntouch /tmp/1234567890_'"$RUN"
Run Code Online (Sandbox Code Playgroud)

它本身或单词结尾时也没有扩展; 这不是那么干净但是:

printf "#%c/bin/bash\ntouch /tmp/1234567890_$RUN" !
Run Code Online (Sandbox Code Playgroud)

您也可以通过(临时)设置$histchars为空字符串暂时关闭历史记录替换; 这关闭了特殊处理!:

histchars=
printf "#!/bin/bash\ntouch /tmp/1234567890_$RUN"
unset histchars
Run Code Online (Sandbox Code Playgroud)

或者您可以printf在脚本中而不是以交互方式执行命令(默认情况下,仅在交互式shell中启用历史记录替换).


Gil*_*not 9

试着这样做:

printf "\041"
Run Code Online (Sandbox Code Playgroud)

这是!字符的八进制ASCII表示

看到

man ascii
Run Code Online (Sandbox Code Playgroud)

另一种方案:

(
    set +o histexpand 
    printf "!"
)
Run Code Online (Sandbox Code Playgroud)

(括号用于更改子shell中的终端设置,因此更改是临时的)

看到

help set
set -o
Run Code Online (Sandbox Code Playgroud)