文件描述符和 shell 脚本

Ric*_*o M 35 bash io-redirection shell-script file-descriptors

我很难理解如何在 shell 脚本中使用文件描述符。

我知道基础知识,例如

exec 5 > /tmp/foo
Run Code Online (Sandbox Code Playgroud)

所以 fd 5 附加到 foo 用于写入。

exec 6 < /tmp/bar
Run Code Online (Sandbox Code Playgroud)

……阅读。

exec 5>&-
Run Code Online (Sandbox Code Playgroud)

...关闭fd。

这有什么作用呢?

#!/bin/bash

exec 5 > /tmp/foo 
exec 6 < /tmp/bar 

cat <&6 | while read a
do
     echo $a >&5
done
Run Code Online (Sandbox Code Playgroud)

据我所知,&5关闭了 fd,那么每次调用后输出仍然如何成功重定向?

这是复制意大利面来自:这里

它声称在简单的echo $a > file情况下使用它会使其更快,但我无法理解。我将不胜感激任何指向体面教程的链接。我的谷歌权力似乎让我失望。

Gil*_*il' 50

首先,请注意关闭的语法是5>&-6<&-,这取决于文件描述符是为写入还是为读取而读取。那篇博文中似乎有拼写错误或格式错误。

这是注释脚本。

exec 5>/tmp/foo       # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar       # open /tmp/bar for reading, on fd 6
cat <&6 |             # call cat, with its standard input connected to
                      # what is currently fd 6, i.e., /tmp/bar
while read a; do      # 
  echo $a >&5         # write to fd 5, i.e., /tmp/foo
done                  # 
Run Code Online (Sandbox Code Playgroud)

这里没有关门。因为在这个简单的例子中所有的输入和输出都在同一个地方,所以没有必要使用额外的文件描述符。你可以写

cat </tmp/bar |
while read a; do
  echo $a
done >/tmp/foo
Run Code Online (Sandbox Code Playgroud)

当您想依次写入多个文件时,使用显式文件描述符会很有用。例如,考虑将数据输出到数据输出文件并将数据记录到日志文件以及可能的错误消息的脚本。这意味着三个输出通道:一个用于数据,一个用于日志,一个用于错误。由于输出只有两个标准描述符,因此需要第三个。您可以调用exec打开输出文件:

exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&-  # close the data output file
echo "output file closed" >&3
Run Code Online (Sandbox Code Playgroud)

当您在循环中进行重定向时,就会出现关于效率的评论,如下所示(假设文件一开始是空的):

while …; do echo $a >>/tmp/bar; done
Run Code Online (Sandbox Code Playgroud)

在每次迭代中,程序打开/tmp/bar,查找文件末尾,附加一些数据并关闭文件。一劳永逸地打开文件效率更高:

while …; do echo $a; done >/tmp/bar
Run Code Online (Sandbox Code Playgroud)

当在不同时间发生多个重定向时,调用exec执行重定向而不是在重定向中包装块变得很有用。

exec >/tmp/bar
while …; do echo $a; done
Run Code Online (Sandbox Code Playgroud)

通过浏览io-redirection此站点上的标记,您会发现其他几个重定向示例

  • 关闭文件描述符的两种语法实际上都做同样的事情。 (3认同)