我知道 > 和 >> 运算符,> 通过删除旧内容将某些内容放入文件中,>> 将某些内容附加到文件内容的末尾。
当我只使用
cat > foo
我能够以交互方式向 foo 写入几行,直到按下 ctrl+z,然后结束。
现在,如果我以相反的顺序添加附加运算符和我选择的一些单词
cat > foo << "wordofchoice"
我可以执行与第一种情况相同的操作,但这次每行的开头都会出现 > 提示,并且我无法通过 ctrl+z 结束交互式输入,而是通过键入“wordofchoice”(不带双引号)来结束交互式输入。
为什么会这样,这个表达式背后的逻辑是什么,<<运算符在这里似乎没有附加东西的意义。
答案1
$PS2
- 每次用户
\n
在交互式 shell 中完成命令行之前输入 ewline 时,该变量的值应进行参数扩展并写入标准错误。默认值为>
。
- 每次用户
您会看到 ,>
因为这是 - 的默认值$PS2
,它是 shell 在无法正确分隔包含换行符的命令字符串时将打印的提示字符串。
您的命令字符串无法分隔,因为您尚未关闭带引号的字符串:
- 各种引用机制包括转义字符、单引号和双引号。这里的文档代表了另一种引用形式;看此处文档。
shell 的解析器标记化逐行读取时输入。您已经向它发送了一条\n
ewline - 这也意味着您的终端到目前为止刚刚向它发送了一份命令的副本 - 但它检测到至少一个开放式引号字符串 - 换句话说,一个不完整的命令 - 因此会提示您执行其余的操作的..
- 如果当前字符是
\
反斜杠、'
单引号或"
双引号并且未加引号,则它将影响后续字符的引用,直到被引用文本的末尾。引用规则如下所述引用。在令牌识别期间,不应实际执行任何替换,并且结果令牌应准确包含输入中出现的字符\n
( ewline>加盟除外)\'"
,未经修改,包括引号和引用文本末尾之间的任何嵌入或封闭的引号或替换运算符。令牌不应由引用字段的末尾分隔。
Here-document 是一种特殊的引用形式,因为它也是重定向- shell 将您的输入重定向为由打开令牌<<heredoc_delimiter_string\n
和预期关闭令牌分隔\nheredoc_delimiter_string\n
的command
<<start_here_document
。
这里的文档应被视为一个单词,从下一个
\n
ewline 开始,一直持续到有一行只包含<<delimiter
和一个\n
eline,没有空白的之间的字符。然后下一个此处文档开始(如果有)。格式如下:[n]<<word here-document delimiter
如果您向 shell 的解析器提交了任何其他意味着第二个 shell 标记,但在结束标记之前传递了一个换行符,那么 shell 的行为也会类似。$PS2
例如,如果您在输入ewline 或已经提到的其他引号之一之前for
没有输入就开始循环,则会打印。done
\n
\n
在命令中放置 ewline 的另一种方法是使用终端引用它 - 通常可以使用 逐字引用下一个输入字符CTRL+V
。如果你CTRL+V
那么做CTRL+J
(或\n
eline)通常,您可以在命令字符串中输入文字\n
ewline,而终端无需立即向 shell 发送输入的副本 - 因为通常终端会逐行发送它,但是当您CTRL+V
引用shell 还不会接收换行符,因此不会提示您输入更多内容。
然而,这并不意味着终端引用的换行符也为 shell 正确引用了 - 您需要在适用的情况下使用 shell 引号来执行此操作 - 但它会阻止读取命令字符串,至少,直到您准备提交。