Bash:文件描述符

时间:2013-03-25 01:27:50

标签: bash

我是Bash的初学者,但我正试图学习这个工具,以便在这些日子里找到一份计算机工作。

我正在努力自学文件描述符。让我分享一些我的实验:


#!/bin/bash

# Some dummy multi-line content
read -d '' colours <<- 'EOF'
        red
        green
        blue
EOF

# File descriptor 3 produces colours
exec 3< <(echo "$colours")

# File descriptor 4 filters colours
exec 4> >(grep --color=never green)

# File descriptor 5 is an unlimited supply of violet
exec 5< <(yes violet)

echo Reading colours from file descriptor 3...
cat <&3
echo ... done.

echo Reading colours from file descriptor 3 again...
cat <&3
echo ... done.

echo Filtering colours through file descriptor 4...
echo "$colours" >&4
echo ... done. # Race condition?

echo Dipping into some violet...
head <&5
echo ... done.

echo Dipping into some more violet...
head <&5
echo ... done.

当我看到来自上面的输出时,脑海中浮现出一些问题:

  1. fd3似乎在“消费”后“耗尽”,是否在首次使用后自动关闭?
  2. fd3与命名管道有什么不同? (我已经看过的东西)
  3. 完全命令yes开始执行时?在fd宣言?以后?
  4. yes停止(CTRL-Z或其他)并在需要更多紫罗兰时重启?
  5. 如何获得yes的PID?
  6. 我可以获得“活动”fds列表吗?
  7. 通过fd4过滤非常有趣的竞争条件,可以避免吗?
  8. yes只会在我exec 5>&-
  9. 时停止
  10. 关闭>&-<&-
  11. 是否重要?

    我暂时停在这里。

    谢谢!

    PS:部分(编号)的答案很好..我会把自己不同的部分放在一起..(虽然一个人的综合答案会令人印象深刻!)

1 个答案:

答案 0 :(得分:15)

  

fd3似乎在“消费”后“耗尽”,是否在首次使用后自动关闭?

不,它没有关闭。这是由于exec的工作方式。在您使用exec(不带参数)的模式中,它的功能是按照指定给自己的I / O重定向()的要求排列shell自己的文件描述符,然后将它们保留为< / strong>直到脚本终止或稍后再次更改。

稍后,cat在其标准输入(文件描述符0)上接收此文件描述符3的副本。当cat退出时,cat的标准输入会被隐式关闭(或者,尽管不太可能,但cat在它存在之前将其关闭,但这并不重要)。此文件的原始副本(shell的文件描述符3)仍然存在。虽然实际文件已达到EOF,但不会从中读取任何内容。

  

fd3与命名管道有何不同? (我已经看过的东西)

shell的<(some command)语法(不是标准的bourne shell语法,我相信只在zshbash中可用,顺便说一下)实际上可能是使用命名管道实现的。它可能不在Linux下,因为有更好的方法(使用/dev/fd),但它可能在其他操作系统上。

因此,从这个意义上说,这种语法可能也可能不是设置命名管道的帮助器。

  

命令是什么时候开始执行?在fd宣言?以后?

评估<(yes violet)构造时(在评估exec 5< <(yes violet)时会发生这种情况)。

  

是否停止(CTRL-Z或其他)并在需要更多紫罗兰时重新启动?

不,它不会停止。但是,当它开始产生的输出比读取管道另一端正在消耗的任何东西时,它将很快阻止。换句话说,管道缓冲区将变满。

  

我怎样才能获得“是”的PID?

好问题!在$!执行后,yes似乎立即包含它。然而,似乎有一个中间子shell,你实际上得到了该子shell的pid。请尝试<(exec yes violet)以避免中间过程。

  

我可以获得“活跃”fds的列表吗?

不是来自shell。但是,如果您使用的是具有/proc的Linux操作系统,则可以咨询/proc/self/fd

  通过fd4过滤非常有趣的竞争条件,可以避免吗?

为避免这种情况,您可能希望在继续执行脚本之前等待grep进程完成。如果您获得该流程的流程ID(如上所述),我认为您应该能够wait

  

只有当我执行5&gt;&amp; - ?

时才会停止

是。接下来会发生的是yes将继续尝试永久产生输出,但当文件描述符的另一端关闭时,它将获得写入错误(EPIPE)或信号({ {1}})默认情况下是致命的。

  

我是否关闭&gt;&amp; - 或&lt;&amp; - ?

是否重要?

没有。两种语法都是为了保持一致。