【问题标题】:Perl: Check if shell has redirected file handlePerl:检查外壳是否已重定向文件句柄
【发布时间】:2013-07-14 19:32:50
【问题描述】:

我想测试我的 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 的解决方案。

【问题讨论】:

  • 为什么?在每种情况下表现不同的实用程序不会违反最基本的 Unix 原则吗?
  • 抛开 Unix 原则,如此复杂的原因是什么,为什么需要从外部选择文件描述符?
  • 您的示例都没有打开给定描述符上的文件。您的示例假定 my_program 已打开它们,并且写入它们的任何内容都将被重定向到给定文件。
  • 其实他的例子确实打开了描述符3。程序是否使用它是另一个问题。

标签: perl shell file-io file-descriptor


【解决方案1】:

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

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

小问题是 fd 62 及更高版本被 bash 用于

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多