【问题标题】:How to printf an exclamation mark in bash? [duplicate]如何在bash中打印感叹号? [复制]
【发布时间】:2013-02-07 08:11:50
【问题描述】:

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

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 必须在文件中。由于某种原因,执行脚本的二进制文件不会读取该文件。

【问题讨论】:

    标签: linux bash unix scripting


    【解决方案1】:

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

    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 启用)。

    【讨论】:

    • 啊,有道理。
    • 好收获......!
    • @David:我已经更新了我的答案,提供了更多选择。
    【解决方案2】:

    尝试这样做:

    printf "\041"
    

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

    man ascii
    

    另一种解决方案:

    (
        set +o histexpand 
        printf "!"
    )
    

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

    help set
    set -o
    

    【讨论】:

    • 谢谢!我没想到。
    • 其实这只在单引号中有效,printf '!' 也是如此。
    • 在我编辑的帖子中查看我的第二个解决方案
    • 这也适用于单引号和双引号,就像我的帖子中一样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2015-05-01
    • 2018-03-18
    • 2015-06-01
    • 2019-01-31
    • 1970-01-01
    • 2017-06-11
    相关资源
    最近更新 更多