我是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.
Run Code Online (Sandbox Code Playgroud)
当我看到来自上面的输出时,有些问题浮现在脑海中:
yes开始执行?在fd宣言?后来?yes停止(CTRL-Z或其他),并需要更多的紫色时重新启动?yes?yes只有当我停下exec 5>&-?>&-或是否关闭<&-?我现在就到此为止.
谢谢!
PS:部分(编号)的答案很好..我会把自己的不同部分放在一起..(虽然一个人的综合答案会令人印象深刻!)
Cel*_*ada 15
fd3似乎在"消费"后"耗尽",是否在首次使用后自动关闭?
不,它没有关闭.这是由于exec工作方式.在您使用exec(不带参数)的模式中,其功能是按照指定给自身的I/O重定向的要求排列shell自己的文件描述符,然后将它们保留,直到脚本终止或再次更改为止后来.
稍后,cat在其标准输入(文件描述符0)上接收该文件描述符3的副本.退出cat时隐式关闭标准输入cat(或者,尽管不太可能,cat但在它存在之前将其关闭,但这并不重要).此文件的原始副本(shell的文件描述符3)仍然存在.虽然实际文件已达到EOF,但不会再从中读取任何内容.
fd3与命名管道有什么不同?(我已经看过的东西)
shell的<(some command)语法(这不是标准的bourne shell语法,我相信只有zshand bash,顺便说一句)可能实际上是使用命名管道实现的.它可能不在Linux之下,因为有更好的方法(使用/dev/fd),但它可能在其他操作系统上.
所以从这个意义上讲,这种语法可能也可能不是设置命名管道的帮助器.
什么时候命令是开始执行?在fd宣言?后来?
一旦<(yes violet)构造被评估(在exec 5< <(yes violet)评估时发生).
肯定停止(CTRL-Z或其他)并在需要更多紫罗兰时重新启动?
不,它不会停止.但是,当它开始产生的输出比读取管道另一端正在消耗的任何东西时,它将很快阻止.换句话说,管道缓冲区将变满.
我怎么能得到是的PID?
好问题!执行$!后似乎立即包含它yes.然而,似乎有一个中间子shell,你实际上得到了该子shell的pid.尽量<(exec yes violet)避免中间过程.
我可以获得"活跃"fds列表吗?
不是来自shell.但是,如果你使用像Linux这样的操作系统/proc,你可以咨询/proc/self/fd.
通过fd4过滤非常有趣的竞争条件,可以避免吗?
为避免这种情况,您可能希望grep在继续执行脚本之前等待该过程完成.如果您获得该流程的流程ID(如上所述),我认为您应该能够获得该流程wait.
只有当我执行5>& - 时才会停止
是.接下来会发生的是yes将继续尝试永久产生输出,但是当文件描述符的另一端关闭时,它将获得写入错误(EPIPE)或SIGPIPE默认情况下致命的信号().
是否与>& - 或<& - ?关闭是否重要?
不可以.两种语法都是为了一致性而提供的.