【问题标题】:echo newline character outputecho 换行符输出
【发布时间】:2014-03-26 21:44:29
【问题描述】:

我正在写一个 bash 脚本,当我写这行时:

echo "l=l.split('\n')"

我希望输出实际上是 l=l.split('\n') 但得到:

l=l.split(' ')

关于如何解决这个问题的任何想法?我尝试在不同的位置使用引号并以不同的方式转义字符,但似乎没有任何效果。感谢您的帮助!

**值得注意 - 如果我只是在终端中输入 echo 命令,我会得到我想要的输出。不知道为什么脚本会被区别对待。

【问题讨论】:

  • 转义\ in \n: echo "l=l.split('\\n')"?
  • 刚刚再次尝试该解决方案并收到输出:l=l.split( ').. 除了括号中的第一个撇号丢失之外,基本上相同
  • 它适用于我使用 bash 4.2.37;我在输出中得到\n。
  • 哪种方式有效? @KeithThompson
  • @15tigers:echo "l=l.split('\n')" 和 echo "l=l.split('\\n')" 都为我打印 l=l.split('\n')。

标签: bash shell echo newline


【解决方案1】:

听起来你可能弄错了shebang(无论如何,对于bash 脚本)。举个例子:

$ cat test.sh
#!/bin/sh

echo "l=l.split('\n')"
$ ./test.sh
l=l.split('
')
$ cat test.bash
#!/bin/bash

echo "l=l.split('\n')"
$ ./test.bash
l=l.split('\n')

尽管bash 和sh 在某些系统上可能由同一个shell 提供,但它们的行为存在细微差别。如果您希望它在终端中的行为与您在终端中的行为一样,请务必使用#!/bin/bash。

【讨论】:

  • +1 - 我确实认为这是问题所在;我的猜测是 OP 使用 OSX,你描述的差异适用。
【解决方案2】:

tl;dr

  • 如果您的脚本确实是由 bash 运行的,那么肯定有某些东西打开了默认关闭的 xpg_echo shell 选项 - 直接或间接通过 shell当 Bash 以 sh (/bin/sh) 调用时,选项 posix。
    posix隐式打开,例如在 macOS 上发生。

    李>
  • 如果您的脚本不是由bash 运行,这是最可能的解释,正如FatalError's helpful answer 中所建议的那样:

    • 确保脚本的 shebang 行是
      #!/bin/bash 或 #!/usr/bin/env bash。

    • 或者,直接将其传递给bash:bash <script>

  • 便携式解决方案,可以保护您免受变量echo 行为的影响,如下使用printf:

    printf '%s\n' "l=l.split('\n')"
    

可选的背景信息

在bash中,echo对\n等转义序列的解释默认关闭。

必须打开选项xpg_echo,echo 才能识别转义序列。

如果您在 POSIX 兼容模式下运行 bash(使用 shopt -o posix 验证),则此选项隐式启用,如果您运行 Bash,也会发生这种情况如sh,如 ma​​cOS 上的情况,例如,/bin/sh 是 Bash。

请注意,无论xpg_echo 本身的状态如何,您都可以使用echo -e 选择加入转义序列解释,并使用echo -E 选择退出。

但是,这在 POSIX 兼容模式 (shopt -o posix) 下运行时不起作用,其中 - 符合 POSIX - echo 不支持选项。

换句话说:只有在 (a) 您的脚本确实由 bash 执行并且 (b) 选项 posix 为 关闭 时,以下操作才有效:

echo -E "l=l.split('\n')"

同样,printf 是 便携式,POSIX-compliant alternative可以在所有 POSIX 兼容的 shell 中始终如一地工作,无论 shell 选项的状态如何:

# '%s\n': *without* escape-sequence interpretation
$ printf '%s\n' "l=l.split('\n')"
l=l.split('\n')

# '%b\n': *with* escape-sequence interpretation
$ printf '%b\n' "l=l.split('\n')"
l=l.split('
')

【讨论】:

    【解决方案3】:

    这样就解决了问题。

    echo "l=l.split('\\\n')"
    

    【讨论】:

    • 对我来说,打印 l=l.split('\\n') (bash 4.2.37)。
    • 使用 bash 4.2.45,这是行不通的,而且 @ExP 注释也行。
    • 哦...我现在看到了。 sh file.sh 给出正确的输出,bash file.sh 给出额外的 '\'。
    • 提问者可能正在使用sh 运行文件。
    • 不知道为什么,但这个答案对我有用,我使用的是 bash 版本 3.2.51。不完全确定如何升级,但会调查它。谢谢大家!
    猜你喜欢
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2014-10-24
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多