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

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

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

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

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

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

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

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

答案1

read(fd, 0, 0)在 C 语言中,使用或可以很容易地进行检查(fcntl(fd, F_GETFL) & O_WRONLY) == 0。我无法欺骗任何标准实用程序来执行此操作,因此这里有一些可能的解决方法。

在 Linux 上,您可以使用/proc/PID/fdinfo/FD

if [ ! -d "/proc/$$/fd/$fd" ] && grep -sq '^flags.*[02]$' "/proc/$$/fdinfo/$fd"; then
    echo "$fd" is valid for input
fi

在 OpenBSD 和 NetBSD 上,您可以将/dev/fd/FDanddd与零计数一起使用:

if dd if=/dev/fd/3 count=0 3<&"$fd" 2>/dev/null; then
    echo "$fd" is valid for input
fi

在 FreeBSD 上,默认情况下仅提供前 3 个 fd /dev/fd;;您应该安装fdescfs(5)/dev/fd或:

if (dd if=/dev/fd/0 count=0 <&"$fd") 2>/dev/null; then
    echo "$fd" is valid for input
fi

笔记:

在某些系统上,bash它的模拟/dev/fd/FD,因此cat </dev/fd/7可能与cat /dev/fd/7.同样的警告适用于gawk.

read(2)长度为 0(或者其标志中open(2)没有长度)的 A将O_TRUNC不是更新访问时间或任何其他时间戳。

在 Linux 上,read(2)即使打开了目录,a 也总是会失败没有旗帜O_DIRECTORY。在其他 Unix 系统上,可以像读取另一个文件一样读取目录。

标准未指定是否dd count=0不复制任何块或全部来自文件的块:前者是 GNU dd ( gdd) 和dd*BSD 的行为。

答案2

这似乎适用于 linux bash

if read -u $fd -n 0 -t 0 2>/dev/null
then
 ....
fi 

相关内容