【问题标题】:Why can't I echo the characters #! in a string in bash? [duplicate]为什么我不能回显字符#!在 bash 的字符串中? [复制]
【发布时间】:2014-02-01 04:52:31
【问题描述】:

我有一个很小的 ​​bash 脚本,它应该移动到我的主目录,创建一个文件,在上面回显一些垃圾,并使其可执行。这是它的样子:

cd ; touch tor.sh; echo "#!/bin/bash\n/usr/local/bin/tor" >> tor.sh; chmod +x tor.sh

但这一直在回声中中断,抱怨“未找到事件”?出于某种原因,我决定尝试一下,它奏效了:

cd ; touch tor.sh; echo -e "\x23\x21/bin/bash\n/usr/local/bin/tor" >> tor.sh; chmod +x tor.sh

为什么我必须用十六进制和 -e 替换这两个字符(shebang?)?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: bash


    【解决方案1】:

    这不是错误,它与shebang无关,只是感叹号。

    Enclosing  characters  in double quotes preserves the literal value of
    all characters within the quotes, with the exception of $, `, \,  and,
    when  history expansion is enabled, !.
    

    所以要么转义它,使用单引号,要么关闭历史扩展。

    例如

    > echo "How dare you put an '!' in this string?"
    bash: !: event not found
    > set +o histexpand
    > echo "How dare you put an '!' in this string?"
    How dare you put an '!' in this string?
    

    【讨论】:

    • 你的回答用最直接的方式解释了我的问题的原因,这也是我更关心的部分。但如果可以的话,我也会接受 Red Cricket 的回答。
    【解决方案2】:

    你应该使用单引号来防止字符串外推:

    echo '#!/bin/bash\n/usr/local/bin/tor'
    

    或者你可能会逃离shebang:

    echo "#\!/bin/bash\n/usr/local/bin/tor"
    

    【讨论】:

      【解决方案3】:

      试试''s 而不是"'s 这样...

      $ echo '#!/bin/bash' > thing.sh
      $ cat thing.sh
      #!/bin/bash
      

      【讨论】:

        【解决方案4】:

        使用“\”,如:

        echo \#\!/whatever > test
        

        【讨论】:

          【解决方案5】:

          两个原因:

          一,双引号和单引号字符串在行为上的区别。

          "#!/bin/bash\n/usr/local/bin/tor" 是“扩展的”——也就是说,这里引号内的命令将首先执行。

          因此,
          echo "$(echo foo)" > file 将“foo”放入 file,而
          echo '$(echo foo)' > file 放入 file 中的“$(echo foo)”。

          “#!”是注释,这在其他 shell 中不会发生。如果它开始一个文件(作为一个 shebang),POSIX 指定这是未定义的行为;但是没有理由在这里发生这种情况。

          【讨论】:

          • 这里是对treatment and effect of string expansion的一些更高级的讨论。
          • 我没有足够的声誉来评论别人的答案,所以我想我会把它放在这里:我坚持称这是一个错误。 here 没有指定该行为;这不能在任何其他 shell 中复制(dash ksh mksh pdksh yash)。如果是 bashism,则在使用 bash --posix 调用时应禁用此功能。
          • 那么在其他shell中不能复制的都是bug?
          • 兄弟,我没有兴趣和你进行一场激烈的战争。当然不是;声称正在实施标准是一个错误,特别是在严格兼容的模式下,以引入不同且不兼容的行为(另外,没有关于这种偏差的文档)。
          • 您认为我的回答中的引用来自哪里?
          猜你喜欢
          • 1970-01-01
          • 2016-12-30
          • 2015-06-27
          • 1970-01-01
          • 1970-01-01
          • 2016-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多