有没有一种方法可以在Perl中找到stdout重定向到的文件的名称



与为Python编写的问题相同,但再次询问Perl,因为它们是不同的脚本语言,可能还有不同的功能集。

通常,我想检测我的Perl脚本的STDINSTDOUT是否被重定向(最好是前者(。与其知道文件名,我更想知道调用者是否正在使用重定向,这样,如果他们没有,我就可以向他们提供"帮助文本"。

最好是独立于平台的,但我只预计这个脚本会在macOS或Linux上运行。

您可以检查句柄是否为终端,是否使用-t

if (-t STDOUT) {
say "Terminal";
} else {
say "Not a terminal or an error occured"; 
}

defined( my $rv = -t STDOUT )
or die("Can't check if STDOUT is a terminal: $!n");
if ($rv) {
say "Terminal";
} else {
say "Not a terminal"; 
}

无论是否为终端,您都可以找到它是什么类型的文件。

stat(STDOUT)
or die("Can't stat STDOUT: $!n");
if    (-f _) { say "Plain file";       }
elsif (-p _) { say "Pipe";             }
elsif (-S _) { say "Socket";           }
elsif (-c _) { say "Character device"; }
elsif (-b _) { say "Block device";     }
else         { say "Something exotic"; }  # Impossible?

一个终端将是一个字符设备,但并不是所有的字符设备都是终端。


除了模块之外,不可能以独立于系统的方式(如果有的话(确定与哪个文件相关(如果它甚至有名称(。

在Linux上,您可以使用/proc

$ perl -e'warn readlink("/proc/$$/fd/".fileno(STDOUT))."n"'
/dev/pts/0
$ perl -e'warn readlink("/proc/$$/fd/".fileno(STDOUT))."n"' >a
/tmp/ikegami/a
$ perl -e'unlink "a";
warn readlink("/proc/$$/fd/".fileno(STDOUT))."n"' >a
/tmp/ikegami/a (deleted)
$ perl -e'warn readlink("/proc/$$/fd/".fileno(STDOUT))."n"' |cat
pipe:[27807]
$ perl -le'print(-t STDIN ? "terminal" : "file")'
terminal
$ perl -le'print(-t STDIN ? "terminal" : "file")' < /dev/null
file
$

最新更新