Kus*_*nda 5 shell file-descriptors
在问题“测试文件描述符是否有效”中,寻求测试是否打开文件描述符。
答案都集中在测试文件描述符是否为输出打开,但如何测试文件描述符是否为输入打开?
这是在另一个问题的答案的评论线程中出现的,答案是这样解释的,
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就不会抱怨)或它是否已关闭?
在 C 中使用read(fd, 0, 0)或很容易进行检查(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
Run Code Online (Sandbox Code Playgroud)
在 OpenBSD 和 NetBSD 上,您可以使用/dev/fd/FD和dd零计数:
if dd if=/dev/fd/3 count=0 3<&"$fd" 2>/dev/null; then
echo "$fd" is valid for input
fi
Run Code Online (Sandbox Code Playgroud)
在 FreeBSD 上,默认只提供前 3 个 fds /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
Run Code Online (Sandbox Code Playgroud)
笔记:
在某些系统上,bash它的模拟/dev/fd/FD,因此cat </dev/fd/7可能与cat /dev/fd/7. 同样的警告适用于gawk.
甲read(2)长度为0(或open(2)没有O_TRUNC在其flags)将不更新访问时间或其他任何时间戳。
在Linux上,一个read(2)总是失败的一个目录,即使它被打开了,而不该O_DIRECTORY标志。在其他 Unix 系统上,一个目录可能像另一个文件一样被读取。
该标准未指定是否从文件中dd count=0复制任何块或所有块:前者是 GNU dd ( gdd) 和ddfrom *BSD 的行为。
| 归档时间: |
|
| 查看次数: |
1569 次 |
| 最近记录: |