我尝试将以下两个命令复制粘贴到终端中直接地然后执行它们:
read -s x
read -s y
当前输出为空提示,但所需输出是第一次read
执行,然后是第二次read
执行。
我可以通过以下方法克服这个问题:
read -s x &&
read -s y
但;
为什么两个或多个读取命令不能一次性执行(没有某种分隔语法)?
答案1
<newline>
默认情况下,无论字符是粘贴文本的一部分还是用户键入的字符,对于终端来说都没有任何区别。当你粘贴时
read -s x
read -s y
after<newline>
使read -s x
您的终端将该行发送到您的 shell。 shell 解析它,发现它是一个完整的命令端,因此执行它:read
然后等待标准输入上的内容,终端向它提供行read -s y
,最终设置为 的值x
。
它的工作方式大致就像您键入read -s x
、按下Enter、键入read -s y
、Enter再次按下一样。
您是否需要额外的Enter操作、 的值到底x
是什么、实际打印出什么以及后续行会发生什么取决于您的 shell 以及它设置终端的模式。例如,使用 Bash 5.0 并假设剪贴板中的两行均以<newline>
,
# Pasting with Ctrl + Shift + v, Enter
$ read -s x
$ # The prompt comes back after pressing Enter again
$ declare -p x y
"eclare -- x="read -s y
bash: declare: y: not found
(declare
的输出看起来很混乱,因为当行编辑处于活动状态(默认)时, Bash 将终端配置为不\r
将(回车)转换为(换行);当第一个指示终端启用→转换时,终端有\n
read
\r
\n
已经将 a (按下或粘贴换行时\r
发送的字符)放在第二个粘贴行之后到缓冲区中,导致将其逐字添加到 的值并要求您按下以表示输入结束)。Enterread
x
Enter
如果您粘贴,则不会发生这种情况
read -s x &&
read -s y
因为 shell 解析read -s x &&
为不完整的“AND”列表并等待更多输入,直到可以运行完整的命令。
你的方式能一次粘贴多个命令是使用“括号粘贴”,这是一种终端模式,其中粘贴的文本作为单个字符串插入到缓冲区中,而不是被视为手动键入。
重击支持它从 4.4 版本开始。您可以通过添加来启用它
set enable-bracketed-paste on
到 Readline 初始化文件(默认情况下为~/.inputrc
)。
兹什支持它从版本 5.1 开始,当 ZLE(Zsh 行编辑器)处于活动状态时,它默认启用。
有关其工作原理以及如何启用它的更多详细信息,请参阅:
- 为什么终端在粘贴文本后自动输入我的命令?
- 防止 bash 中的多行粘贴(还介绍了如何在 Bash 中启用括号粘贴)
答案2
您将需要某种分隔语法,否则它将如何知道一个read
命令在哪里结束以及下一个命令在哪里开始?
如果第一个没有返回任何错误,则使用&&
只会执行第二个。read
如果你希望第二个总是执行,你可以;
这样使用:
read -s x ; read -s y
但我不清楚你是否想执行一个read
并将其存储在变量中x
,然后执行第二个read
并将其存储在y
或者如果您想执行一个read
并将相同的结果存储在x
和中y
。我的建议是前者。