关于Bash中管道的工作原理,有什么简单的解释?
我经常在Bash中使用管道,例如:关于Bash中管道的工作原理,有什么简单的解释?,bash,pipe,Bash,Pipe,我经常在Bash中使用管道,例如: dmesg | less 虽然我知道这会输出什么,但它需要dmesg并允许我用更少的滚动它,但我不明白在做什么。它仅仅是>的反面吗 对于|的作用,是否有一个简单的或隐喻性的解释 在一条管线中使用多条管道时会发生什么 管道的行为在Bash脚本中出现的任何地方都是一致的吗 管道操作符获取第一个命令的输出,并通过连接stdin和stdout将其“管道”到第二个命令。 在您的示例中,dmesg命令的输出不是发送到stdout(并将其发送到控制台),而是直接发送到下
dmesg | less
虽然我知道这会输出什么,但它需要dmesg
并允许我用更少的滚动它,但我不明白
在做什么。它仅仅是>
的反面吗
- 对于
|
的作用,是否有一个简单的或隐喻性的解释
- 在一条管线中使用多条管道时会发生什么
- 管道的行为在Bash脚本中出现的任何地方都是一致的吗
管道操作符获取第一个命令的输出,并通过连接stdin和stdout将其“管道”到第二个命令。
在您的示例中,dmesg命令的输出不是发送到stdout(并将其发送到控制台),而是直接发送到下一个命令 Unix管道将第一个进程的STDOUT(标准输出)文件描述符连接到第二个进程的STDIN(标准输入)。然后发生的情况是,当第一个进程写入其标准输出时,第二个进程可以立即读取该输出(从标准输入)
使用多个管道与使用单个管道没有什么不同。每个管道都是独立的,只是将相邻进程的标准输出和标准输入链接起来
你的第三个问题有点模棱两可。是的,管道本身在bash脚本中的任何地方都是一致的。但是,管道字符|
可以表示不同的内容。例如,双管道(|
)表示“或”运算符。
|
将左侧命令的STDOUT置于右侧命令的STDIN
- 如果您使用多个管道,它只是一个管道链。第一个命令输出设置为第二个命令输入。第二个命令输出设置为下一个命令输入。等等
- 它在所有基于Linux/widows的命令解释器中都可用
Unix中的每个标准进程至少有三个文件描述符,它们有点像接口:
- 标准输出,即进程打印其数据的位置(大部分时间是在控制台,即您的屏幕或终端)
- 标准输入,即它获取数据的位置(大多数情况下,它可能类似于键盘)
- 标准误差,即误差和有时其他带外数据出现的位置。现在这并不有趣,因为管道通常不会处理它
管道将左侧流程的标准输出连接到右侧流程的标准输入。您可以将其视为一个专用程序,负责复制一个程序打印的所有内容,并将其提供给下一个程序(管道符号后面的程序)。不完全是这样,但这是一个足够的类比
每个管道只运行两件事:左边的标准输出和右边的输入流。其中每一个都可以附加到单个进程或管道的另一位,这在多管道命令行中就是如此。但这与管道的实际操作无关;每个管道都有自己的功能
重定向操作符(
)执行一些相关但更简单的操作:默认情况下,它将进程的标准输出直接发送到文件。正如你所看到的,它不是管道的对立面,而是互补的。与
相反的是管道获取进程的输出,我所说的输出是指标准输出(stdout
在UNIX上),并将其传递到另一个进程的标准输入(stdin)
。它不是简单的右重定向的相反,右重定向的目的是将一个输出重定向到另一个输出
例如,以Linux上的echo命令为例,它只是在标准输出上打印传入参数的字符串。如果使用以下简单重定向:
echo "Hello world" > helloworld.txt
shell将重定向最初打算在stdout上的正常输出,并将其直接打印到文件helloworld.txt
现在,以管道为例:
ls-l| grep helloworld.txt
ls
命令的标准输出将在grep输入时输出,那么这是如何工作的呢
像grep
这样的程序在没有任何参数的情况下使用时,只是在读取并等待在其标准输入(stdin)
。当grep捕获到诸如ls命令的输出之类的内容时,它会通过查找正在搜索的内容来正常工作。如果将每个unix命令视为一个独立的模块,
但是,您需要他们使用文本作为一致的界面进行交谈,
怎样才能做到呢
cmd input output
echo "foobar" string "foobar"
cat "somefile.txt" file *string inside the file*
grep "pattern" "a.txt" pattern, input file *matched string*
你可以说,|
是接力马拉松中传递接力棒的隐喻。
它的形状甚至像一个
cat->echo->less->awk->perl
类似于cat | echo | less | awk | perl
cat“somefile.txt”| echo
cat
将其输出传递给echo
使用
当有多个输入时会发生什么情况?
cat“somefile.txt”| grep“pattern”
对于grep
,
通过经验,您将慢慢发展了解哪个参数是哪个参数的眼光。管道非常简单,如下所示
您有一个命令的输出。可以使用管道将此输出作为另一个命令的输入。可以根据需要使用管道传输任意多个命令
例:
ls | grep my | grep文件
首先列出工作目录中的文件。该输出由grep命令检查单词“my”。该命令的输出现在进入第二个grep命令,该命令最终搜索单词“files”。就这样
> program_1 | program_2 | ... | program_n
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
> program_1 | program_2 | program_3