Wit*_*iko 17 bash file-descriptors
我想让 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_WRONLY和 O_RDWR测试的FD是否可写,和O_RDONLY和 O_RDWR测试的FD是否可读)。
Sté*_*las 16
在ksh(AT&T 和 pdksh 变体)或 中zsh,您可以执行以下操作:
if print -nu3; then
echo fd 3 is writeable
fi
Run Code Online (Sandbox Code Playgroud)
他们不会在那个 fd 上写任何东西,但仍然检查 fd 是否可写(使用fcntl(3, F_GETFL)),否则报告错误:
$ ksh -c 'print -nu3' 3< /dev/null
ksh: print: -u: 3: fd not open for writing
Run Code Online (Sandbox Code Playgroud)
(您可以重定向到/dev/null)。
使用bash,我认为您唯一的选择是检查 a 是否dup()像您的方法一样成功,尽管这并不能保证 fd 是可写的(或调用外部实用程序 ( zsh/ perl...) 来执行fcntl())。
请注意,在bash(与大多数 shell 一样)中,如果您使用(...)代替{...;},则会产生一个额外的进程。您可以使用:
if { true >&3; } 2<> /dev/null
Run Code Online (Sandbox Code Playgroud)
而是避免分叉(除了在 Bourne shell 中,重定向复合命令总是会导致子 shell)。不要使用:而不是true因为它是一个特殊的内置函数,所以当 bash 处于 POSIX 合规模式时会导致 shell 退出。
但是,您可以将其缩短为:
if { >&3; } 2<> /dev/null
Run Code Online (Sandbox Code Playgroud)
在 POSIX应用程序使用说明中,您将找到以下内容:command
有时抑制特殊内置函数的特性有一些好处。例如:
Run Code Online (Sandbox Code Playgroud)command exec > unwritable-file不会导致非交互式脚本中止,以便脚本可以检查输出状态。
这就是为什么你可以这样做:
if command >&3
then echo 3 is open >&3
else ! echo 3 is not open
fi 2<>/dev/null
Run Code Online (Sandbox Code Playgroud)
或者...
{ command >&3
printf %s\\n%.0d string "0$(($??8:0))" >&"$(($??1:3))"
} 2<>/dev/null
Run Code Online (Sandbox Code Playgroud)
它将写入字符串后跟一个\newline 到 stdout 或 3 并且在 3 未打开时仍然传递非零退出状态,因为完成的数学运算$?最终未能将八进制08转换为%decimal但截断为空八进制00。
或者...
command exec >&3 || handle_it
Run Code Online (Sandbox Code Playgroud)
但是,如果您正在使用ksh93,则可以执行以下操作:
fds
Run Code Online (Sandbox Code Playgroud)
获取打开的文件描述符列表。添加-l以查看它们的去向。
| 归档时间: |
|
| 查看次数: |
11298 次 |
| 最近记录: |