【发布时间】:2021-03-24 10:42:08
【问题描述】:
我有执行系统命令的代码:
use strict;
use warnings FATAL => 'all';
use autodie ':default'; # i.e. no "system"
use Devel::Confess 'color';
use Capture::Tiny 'capture';
sub execute {
my $cmd = shift;
my ($stdout, $stderr, $exit) = capture {
system( $cmd )
};
if ($exit != 0) {
say "exit = $exit";
say "STDOUT = $stdout";
say "STDERR = $stderr";
die "$cmd failed";
}
return 0
}
根据我之前收到的建议
How to get Capture::Tiny to print stderr and stdout upon failure?
但是,当命令的输出给出某种提示或警告时,此子例程不能很好地工作,并且只会永远挂起而不是打印错误消息/提示。
挂起通常发生在各种 LaTeX 命令中,但由于 LaTeX 没有提供非常好的最小工作示例,如果试图删除没有写入权限的文件,也会产生类似的挂起,没有打印/显示错误,
例如chmod a-w tmp
然后调用脚本execute('rm tmp'),这通常会在 CLI 上给出这个问题:rm: remove write-protected regular file 'tmp'?
但只是挂起,输出时没有打印任何内容。
我尝试将system( $cmd ) 更改为 eval { system( $cmd ) },但仍然看不到错误消息。
如何更改上面的子例程,以便在没有写入权限的情况下尝试删除文件时得到提示和错误?
【问题讨论】:
-
您在输出退出后打印输出。但它不会退出,因为它正在等待输入。所以它完全按照你的要求做。如果您想在程序退出之前打印输出,
system不会成功。我会使用 IPC::Run -
@ikegami 如何在
system退出之前打印输出?给定当前代码,我没有看到提示 -
如果你想在程序退出前打印输出,
system就不行了。我会使用 IPC::Run。 -
metacpan.org/pod/IPC::System::Simple 那里没有任何东西可以同时捕获退出代码、标准输出和标准错误,我如何使用 IPC::System::Simple 做到这一点?
-
不,I::S:S 只提供阻塞等待子进程的函数
标签: perl