在 bash 中为什么可以正常工作:
$ cat test1.sh
#!/bin/bash
echo "some text" \
"some more text"
$ ./test1.sh
some text some more text
但这失败了
$ cat test2.sh
#!/bin/bash
text="some text" \
"some more text"
echo $text
$ ./test2.sh
./test2.sh: line 3: some more text: command not found
我期待两者test1.sh
并test2.sh
做同样的事情。
答案1
未加引号的 <backslash> 应保留后续字符的文字值,但 <newline> 除外。如果 <newline> 跟在 <backslash> 后面,shell 会将其解释为行继续。在将输入拆分为标记之前,应删除 <backslash> 和 <newline>。由于转义的 <newline> 已从输入中完全删除,并且不被任何空格替换,因此它不能用作标记分隔符。
这意味着,在第一个示例中,shell 实际执行的是
echo "some text" "some more text"
这是一个简单的命令echo
,后跟两个参数,在打印到标准输出时使用空格字符连接。
在第二个示例中,shell 实际执行的是
text="some text" "some more text"
echo $text
其中第一行被解释为简单命令some more text
(单个标记,包括空格字符),前面是变量赋值text="some text"
;然后,echo $text
被执行。
为了产生与第一个相同的结果,您的第二个片段可以更改为
text="some text "\
"some more text"
echo "$text"
另请注意, , 中的双引号echo "$text"
需要防止 shell 将分词和文件名生成应用于$text
( 它与示例字符串没有区别,但如果它们包含除单个空格之外的空白字符序列和/或通配符)。
答案2
在 test1.sh 中echo
打印给定的所有参数 -"some text"
是第一个参数,"some more text"
是第二个参数。
而 test2.sh 尝试使用不正确的连接方法连接字符串并分配给变量。
要跨行断开字符串,只需省略结束引号并继续下一行,如下所示:
text="some text \
some more text"