在 Perl 6 中捕获 shell 命令的异常

Catching exception of a shell command in Perl 6

我不得不 运行 一个 shell 程序退出并出现 Perl 6 错误,所以我决定测试它是如何工作的。 我制作了一个 bash 脚本,从 Perl 6 程序向 运行 生成错误:

$ cat prog.sh 
echo "error" >&2
exit 1

这是我在 Perl 6 中的调用方式:

put "start";
  try {
    shell "./prog.sh";
  }
put "end";

输出显示程序在 运行 执行 shell 命令后退出。

start
error
The spawned command './prog.sh' exited unsuccessfully (exit code: 1)
  in block <unit> at b.p6 line 2

如果我添加一个CATCH

put "start";
  try {
    shell "./prog.sh";
    CATCH { default {} }
  }
put "end";

一切正常,程序运行到最后一行:

start
error
end

所以我的问题是:为什么需要添加 CATCH 块,而 try 本身无法解决错误?

shell 直到 sink.

才会抛出 Exception

只有 shelltry 块完全执行而不会抛出异常,return 块中的最后一个值,然后沉没在上下文之外try,然后抛出 Exception.

您可以通过以下方式查看:

put "start";
  try {
    shell "./prog.sh";
    'something';
  }
put "end";

现在 shell 沉入 try 内部,它被 try 的隐式 CATCH 捕获。 try 块 return 是块中的最后一个值,即 'something',然后安全地沉没在 try 之外。

您也可以强制 sinktry 内发生:

put "start";
try {
   sink shell "./prog.sh"
}
put "end";

您添加的 CATCH 块只是阻止 try 块从 return 从 shell.

中获取 return 值

你可以重新排列它们,看看这仍然会爆炸:

put "start";
try {
    CATCH { default {} }
    shell "./prog.sh";
}
put "end";

处理这个恕我直言的最好、最明确的方法是自己检查 shell 中的 return,而不是让它下沉并抛出异常:

put "start";
if shell "./prog.sh" {
    say 'ok'
}
else {
    say 'failed'
}
put "end";