| 和 || 之间的区别

| 和 || 之间的区别

| 和 || 有什么区别?

当我运行此命令时:

ls -la | id

我得到的结果是id

当我运行此命令时:

ls -la || id

我得到的结果是ls -la

那么它们之间有什么区别?

答案1

|是管道运算符,它将第一个命令的输出传递给后面的命令。

man bash

管道是由字符 | 分隔的一个或多个命令序列。管道的格式为:

[time [-p]] [ ! ] command [ | command2 ... ]

command 的标准输出通过管道连接到 command2 的标准输入。

在您提供的示例中,id似乎没有对输出执行任何操作,ls因此它只是返回与单独运行相同的输出id


||是逻辑或运算符,指定如果第一个命令返回false或失败(非零)时要做什么。

man bash

控制运算符 && 和 || 分别表示 AND 列表和 OR 列表。AND 列表的形式为

command1 && command2

当且仅当 command1 返回退出状态零时,才会执行 command2。

OR 列表的形式为

command1 || command2

当且仅当 command1 返回非零退出状态时,才会执行 command2。AND 和 OR 列表的返回状态是列表中执行的最后一个命令的退出状态。

在您的示例中,ls -la运行成功,因此id命令未运行。如果您执行以下操作:

ls -z || id

并尝试将无效选项传递zls,然后它会失败并且id命令会运行。

答案2

|是管道运算符。从man sh

管道是由 | 分隔的一个或多个命令序列。除最后一个命令外,每个命令的标准输出都通过管道 (2) 连接到下一个命令的标准输入。每个命令都作为单独的进程运行;shell 等待最后一个命令终止。管道的值是其最后一个命令的退出状态。

A | B | C

将获取 A 的标准输出(打印到屏幕上的内容)并将其作为标准输入提供给 B,就像您在交互模式下键入的内容一样,然后 B 将其标准输出提供给 C。

history | grep word

history打印出你所有的 shell 的历史记录,并grep打印出与模式匹配的行,所以这会在你的 shell 历史记录中找到你使用过的每个条目word,因为grep在没有给出文件名作为参数时会读取 STDIN。

history | tail -n10 | head -n5 

获取后 10 行的前 5 行history,因为tailhead在没有给出文件名时都读取 STDIN。


另一方面,||逻辑或运算符与 C 和类似 C 语言中的相同运算符完全相同。同样,从man sh

符号 && 和 || 分别表示仅当前面的管道返回零或非零值时才执行后面的列表。列表中可以出现换行符(而不是分号)来分隔命令。

stat filename || echo "no such file or directory" 
stat filename && echo "file exists"

如果stat找不到文件名,它将返回非零的退出状态,如果找到了,它将以 0 成功退出。这是 C 的逆。(stat无论如何,高度设计的例子都会给出这样的信息。)

这些本质上与明确检查最后一个命令的退出状态相同,但更短:

stat filename
if [ $? -gt 0 ]; then
  echo "no such file or directory"
fi

ETC。

相关内容