Zsh:为什么\ n在单引号内解释?

时间:2016-03-29 07:20:36

标签: zsh

根据我的理解,\n应该被解释为

中的新行
"a\nb"
$'a\nb'

但不在

'a\nb'

但是,我看到以下内容:

(来自我的zsh会话的transsscript)

-0-1- ~  > zsh --version
zsh 5.1.1 (x86_64-unknown-cygwin)
-0-1- ~  > echo 'a\nb'
a
b
-0-1- ~  >

3 个答案:

答案 0 :(得分:4)

zsh本身并不解释\n中的'a\nb',但内置echo会解释'a\nb'"a\nb"\n是等效的,不包含换行符,而是包含(文字)字符序列$'a\nb'。另一方面,zsh确实包含换行符。

这里有两件事情可以解决:

1。引用:

引用用于告诉shell您想要一个字符本身,而不是它在shell语法中可能具有的任何特殊含义。 \有四种类型的引用,其中一些可能会保留或为几个字符或字符序列添加特殊含义:

  1. \:通过预先zsh引用单个字符。对于\n来说,n仅表示“我想要角色n”。由于n没有特殊含义,因此与仅编写*相同。这更改为*之类的字符:没有引用\*被用作通配符的通配符,写echo /*会阻止它(例如:比较echo /\*和{{1的输出}})。如果您想直接传递字符\,则必须引用它,例如使用其他\\\
  2. '...':与\一样,任何带有'...'的字符都是字面意思,这包括其他引用方法。 'foo* bar?'基本上等同于foo\*\ bar\?(或\f\o\o\*\ \b\a\r\?,如果一个人想要迂腐)。只有'本身不能出现在引用'...'的字符串中,因为它会标记qoute的结尾。 (可以通过设置RC_QUOTES来更改。如果设置一对单引号作为单引号:'foo''bar'foo\'bar
  3. "...":允许参数和命令替换。这意味着将$之后的单词作为参数名称(例如"path: $PATH"),并将$(...)`...`中包含的字符串用于命令替换(例如echo "Date: $(date)" )。否则,它的行为类似于'...',但允许引用`$\"以及\
  4. $'...':字符串insid $'...'被视为print内置的字符串参数。只有在这里,一些字母字符确实具有特殊含义:换行符\n,退格行为\b,钟声字符\a等。\'可以分别引用\\\'。结果字符串被视为完全引用。 $'...'内有 no 参数或命令替换。
  5. 2。 zsh-builtin echo

    除了echo二进制文件或bash-builtin echo之外,zsh-builtin默认识别(某些)转义序列,如\n\t。虽然这种行为通常需要使用/bin/echo或bash-builtin显式启用(通常通过传递-e标志:echo -e "foo\nbar"),但对于zsh-builtin,需要明确禁用。通过传递-E标记(echo -E 'foo\nbar')或设置BSD_ECHO选项(setopt bsdecho),在这种情况下-e标记可用于重新启用与其他类型的echo一样的功能。

    结论

    这意味着'a\nb'"a\nb"(以及a\\nb这个问题)都会以a\nb(字面意思)传递,但是zsh-builtin {{1}然后解释echo,导致带换行符的输出。另一方面,\n在传递给$'a\nb'之前已包含文字换行符。

    运行

    echo

    应该得到以下输出:

    for quoted_string in a\\nb 'a\nb' "a\nb" $'a\nb'; do
        echo '>' $quoted_string '<'
        /bin/echo -e '>' $quoted_string '<'
        echo -E '>' $quoted_string '<'
        /bin/echo '>' $quoted_string '<'
        echo
    done
    

    正如您所看到的,前三种引用之间没有区别,而第四种始终使用换行符打印。

    BTW:> a b < > a b < > a\nb < > a\nb < > a b < > a b < > a\nb < > a\nb < > a b < > a b < > a\nb < > a\nb < > a b < > a b < > a b < > a b < (至少版本5;我不知道Perl 6)的行为与描述预期行为的方式有关。 perl perl中的行为与'...'中的行为相同。另一方面,zsh"..."的行为类似于perl "..." $'...'的组合:变量被其值和字符序列替换为{{} 1}}和zsh是专门处理的。

答案 1 :(得分:2)

你错误的"a\nb"用换行符替换\n(好吧,不管怎样)。因此,没有标准的引用机制允许字符串中的换行符而不使用文字换行符,如

x="a
b"

这就是发明$'a\nb'符号的原因。截至2016年,它不是POSIX,但POSIX人员正在考虑将其添加到shell specification。一如既往,不要屏住呼吸: - )

答案 2 :(得分:0)

新行是字符,而不是变量,因此没有解释(或扩展)。如果要打印\,则需要将其转义两次,以表示您不想转义不想打印特殊字符的变量

所以你必须使用echo a\\\\nbecho 'a\\nb'