重定向和管道

Tim*_*Tim 6 shell pipe io-redirection

我想知道重定向和管道之间的差异和关系。

  1. 管道是否仅用于将命令的 stdout 输出连接到另一个命令的 stdin 输入?
  2. 重定向是否仅用于将命令的 stdout 输出连接到文件,以及将文件连接到命令的 stdin 输入?但似乎有command >& 2
  3. 管道com1 | com2可以被重定向替换为com1 > tempfile; com2 < tempfile。可以将替换修改为不使用文件吗?
  4. 重定向可以被管道代替吗?

感谢致敬!

Gil*_*il' 8

  1. 是的。更准确地说,在 shell 中,管道将左侧命令的标准输出连接到右侧命令的标准输入。更准确地说,foo | bar对 shell 的意义是:

    1. 创建管道
    2. Fork 一个子进程,并将管道的写端连接到它的标准输出。然后foo在这个子进程中执行。
    3. Fork 一个子进程,并将管道的读取端连接到它的标准输入。然后bar在这个子进程中执行。
    4. 等待两个子进程退出。
  2. 是的。普通重定向按名称指示文件:>foo. 另一种重定向形式通过描述符指示文件。例如,>&2表示“将标准输出重定向到当前连接到的任何文件描述符 2”。

    关于该主题,请注意重定向是从左到右处理的。例如,要将标准输出和标准错误重定向到同一个文件,请使用foo >filename 2>&1. foo 2>&1 >filename在终端中键入的命令首先将标准错误连接到终端(此时标准输出和标准错误仍然连接到终端,因此不会有任何区别),然后将标准输出连接到文件。

  3. 对,但是。shell 中的管道构造创建了一个匿名管道;还有命名管道

    mkfifo f
    cat f
    # (in another terminal)
    echo hello >f
    
    Run Code Online (Sandbox Code Playgroud)

    命名管道比管道少见得多。当需要连接两个独立启动的进程时使用它们;这并不经常发生,但在必要时拥有它是很好的。

    请注意,您提供的替换:foo >tempfile; bar <tempfile不同:首先foo将其所有输出写入临时文件,然后bar开始运行。使用管道,命令并行运行。

  4. 是的,但不是很有用。

    cat input_file | some_command   # a uselessly complicated way of writing some_command <input_file
    echo hello | tee output_file    # a uselessly complicated way of writing echo hello >output_file
    
    Run Code Online (Sandbox Code Playgroud)