10

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

printf "#!/bin/bash\ntouch /tmp/1234567890_$RUN" > /tmp/password-change-script_$RUN.sh

我收到此错误:

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

如果我避开感叹号:

printf "#\!/bin/bash\ntouch /tmp/1234567890_$RUN" > /tmp/password-change-script_$RUN.sh

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

cat /tmp/password-change-script_$RUN.sh
#\!/bin/bash
touch /tmp/1234567890_111

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

4

2 回答 2

16

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

printf '#!/bin/bash\ntouch /tmp/1234567890_'"$RUN"

当它单独出现或出现在词尾时,它也不会被扩展;这不是那么干净,但是:

printf "#%c/bin/bash\ntouch /tmp/1234567890_$RUN" !

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

histchars=
printf "#!/bin/bash\ntouch /tmp/1234567890_$RUN"
unset histchars

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

于 2013-02-21T20:48:18.440 回答
12

尝试这样做:

printf "\041"

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

man ascii

另一个解决方案:

(
    set +o histexpand 
    printf "!"
)

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

help set
set -o
于 2013-02-21T20:44:34.697 回答