我不得不运行一个shell程序退出并出现Perl 6的错误,所以我决定测试它是如何工作的.我做了一个bash脚本产生错误,从Perl 6程序运行它:
$ cat prog.sh
echo "error" >&2
exit 1
Run Code Online (Sandbox Code Playgroud)
以下是我从Perl 6中调用它的方法:
put "start";
try {
shell "./prog.sh";
}
put "end";
Run Code Online (Sandbox Code Playgroud)
输出显示程序在运行shell命令后退出.
start
error
The spawned command './prog.sh' exited unsuccessfully (exit code: 1)
in block <unit> at b.p6 line 2
Run Code Online (Sandbox Code Playgroud)
如果我添加一个CATCH块
put "start";
try {
shell "./prog.sh";
CATCH { default {} }
}
put "end";
Run Code Online (Sandbox Code Playgroud)
一切都很好,程序工作到最后一行:
start
error
end
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:为什么有必要添加CATCH块,而try本身无法解决错误?
shell不会扔到Exception直到sink.
try只有shellin中的块完全执行而没有抛出异常,返回块中的最后一个值,然后在该上下文之外沉没try,然后抛出Exception.
你可以看到这个:
put "start";
try {
shell "./prog.sh";
'something';
}
put "end";
Run Code Online (Sandbox Code Playgroud)
现在shell陷入了内部try,它被隐含CATCH的内容所捕获try.该try块返回块中的最后一个值,即"某事物",然后安全地沉入其中try.
你也可以强迫它sink发生在try:
put "start";
try {
sink shell "./prog.sh"
}
put "end";
Run Code Online (Sandbox Code Playgroud)
你添加的CATCH块只是阻止try块从中返回返回值shell.
你可以重新安排它们,看看它仍然会爆炸:
put "start";
try {
CATCH { default {} }
shell "./prog.sh";
}
put "end";
Run Code Online (Sandbox Code Playgroud)
处理这个恕我直言的最好,最明确的方法是自己检查shell的返回,而不是让它下沉并抛出异常:
put "start";
if shell "./prog.sh" {
say 'ok'
}
else {
say 'failed'
}
put "end";
Run Code Online (Sandbox Code Playgroud)