1

我想测试我的 perl 程序是否被称为:

my_program.pl 3>&1
my_program.pl 3>/tmp/file
my_program.pl 21>my.fifo

或者:

my_program.pl

所以我需要一种perl方法来测试shell是否打开了一个文件描述符。

背景

这旨在作为 GNU Parallel 的可能扩展。目前 GNU Parallel 只确保 STDOUT 和 STDERR 没有混合,所以这会混淆输出:

parallel 'echo begin {} >&3; sleep 1; echo end >&3' ::: a b c 3>/tmp/file

而这不会因为 STDERR 被 GNU Parallel 缓冲:

parallel 'echo begin {} >&2; sleep 1; echo end >&2' ::: a b c 2>/tmp/file

现在无需在未打开的文件句柄上花费资源。这只会失败:

parallel 'echo begin {} >&3; sleep 1; echo end >&3' ::: a b c

因此,如果文件描述符 3 实际上被重定向到 GNU Parallel 之外,则 GNU Parallel 应该只缓冲文件描述符 3。但我不知道如何在 Perl 中检测到这一点。

在 GNU/Linux 上,我可以转到 /proc/$$/fd 并查看打开了哪些描述符,但我更喜欢不依赖于 /proc/*/fd 的解决方案。

4

1 回答 1

1

事实证明这相当容易:只需打开文件描述符的文件句柄。如果失败,则不会打开文件描述符:

perl -e 'for (1..1000) { my $fh; if(open($fh,">&=$_")) {$fh{$_}=$fh }  } print map{"$_\n"} keys %fh'  3>/tmp/foo

次要问题是 fd 62 及更高版本被 bash 用于 <(cmd)。

于 2013-07-13T21:55:34.347 回答