相关疑难解决方法(0)

测试文件描述符是否有效

我想让 bash 脚本在文件描述符(FD)打开时将附加信息输出到大于或等于 3 的文件描述符(FD)。为了测试 FD 是否打开,我设计了以下技巧:

if (printf '' 1>&3) 2>&-; then
  # File descriptor 3 is open
else
  # File descriptor 3 is not open
fi
Run Code Online (Sandbox Code Playgroud)

这足以满足我的需求,但我很好奇是否有更惯用的方法来测试 FD 是否有效。我特别是约是否存在所述的映射感兴趣fcntl(1)系统调用到外壳命令,这将允许FD标志的检索(O_WRONLYO_RDWR测试的FD是否可写,和O_RDONLYO_RDWR测试的FD是否可读)。

bash file-descriptors

17
推荐指数
2
解决办法
1万
查看次数

测试文件描述符是否有效(用于输入)

在问题“测试文件描述符是否有效”中,寻求测试是否打开文件描述符。

答案都集中在测试文件描述符是否为输出打开,但如何测试文件描述符是否为输入打开?

这是在另一个问题的答案的评论线程中出现的,答案是这样解释的,

if [ -n "$1" ]; then
    # read input from file "$1" (we're assuming it exists)
elif [ ! -t 0 ]; then
    # read input from standard input (from pipe or redirection)
else
    # no input given (we don't want to read from the terminal)
fi
Run Code Online (Sandbox Code Playgroud)

问题[ ! -t 0 ]在于,-t如果文件描述符打开与终端关联,则测试为真。如果测试为假,则描述符要么关闭,要么不与终端关联(即我们正在从管道或重定向读取)。[ ! -t 0 ]因此,测试并不能保证文件描述符甚至有效。

如何确定它是否有效(这样read就不会抱怨)或它是否已关闭?

shell file-descriptors

5
推荐指数
1
解决办法
1569
查看次数

为什么 bash "read -t 0" 看不到输入?

我的脚本(应该)表现不同,这取决于输入流中数据的存在。所以我可以这样调用它:

$ my-script.sh
Run Code Online (Sandbox Code Playgroud)

或者:

$ my-script.sh <<-MARK
    Data comes...
    ...data goes.
MARK
Run Code Online (Sandbox Code Playgroud)

或者:

$ some-command | my-script.sh
Run Code Online (Sandbox Code Playgroud)

其中最后两个案例应该读取数据,而第一个案例应该注意到数据丢失并采取相应措施。

脚本的关键部分(摘录)是:

$ my-script.sh
Run Code Online (Sandbox Code Playgroud)

我使用read读取输入数据,然后选择-d ''读取多行,正如预期的那样,并将-t 0超时设置为零。为什么超时?根据help read(打字保持不变;粗体是我的):

-t timeout如果未在几TIMEOUT秒钟内读取完整的输入行,则超时并返回失败。TMOUT 变量的值是默认超时。 TIMEOUT可能是小数。 如果TIMEOUT为 0,则仅当指定文件描述符上的输入可用时 read 才返回成功。如果超时,则退出状态大于 128

所以我在情况 2 和 3 中应该立即读取数据,据我所知。不幸的是它没有。由于-t可以采用小数值(根据上面的手册页),将读取行更改为:

$ my-script.sh <<-MARK
    Data comes...
    ...data goes.
MARK
Run Code Online (Sandbox Code Playgroud)

当数据存在时实际读取数据,如果不存在则跳过它(在 10ms 超时后)。但它也应该在TIMEOUT设置为 real时工作0

为什么它实际上没有?如何解决这个问题?对于“根据数据的存在而采取不同行动”的问题,是否有替代解决方案?

更新

感谢@Isaac,我发现引用的在线版本和我的本地版本之间存在误导性差异(通常我没有将语言环境设置为 en_US,所以help read …

bash read

5
推荐指数
1
解决办法
2029
查看次数

标签 统计

bash ×2

file-descriptors ×2

read ×1

shell ×1