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

时间:2018-10-01 19:53:16

标签: perl6

我必须运行一个退出Perl 6的错误退出的shell程序,所以我决定测试它的工作方式。 我制作了一个SQL> with test (customer, product, amount) as 2 (select 'a', 'table', 500 from dual union all 3 select 'a', 'table', 300 from dual union all 4 select 'a', 'chair', 100 from dual union all 5 select 'b', 'rug' , 50 from dual union all 6 select 'b', 'chair', 200 from dual 7 ) 8 select customer, 9 listagg (product, ', ') within group (order by null) product, 10 sum(sum_amount) amount 11 from (select customer, product, sum(amount) sum_amount 12 from test 13 group by customer, product 14 ) 15 group by customer 16 order by customer; C PRODUCT AMOUNT - -------------------- ---------- a chair, table 900 b chair, rug 250 SQL> 脚本,产生了一个错误,无法从Perl 6程序运行它:

bash

这是我在Perl 6中的称呼:

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

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

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

如果我添加一个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块呢?

1 个答案:

答案 0 :(得分:9)

shell直到sink才抛出Exception

其中仅包含try的{​​{1}}块将完全执行,而不会引发异常,返回该块中的最后一个值,然后将其沉没到shell的上下文之外,然后抛出try

您可以通过以下方式看到此信息:

Exception

现在,外壳陷入put "start"; try { shell "./prog.sh"; 'something'; } put "end"; 内部,并被try的隐式CATCH捕获。 try块返回该块中的最后一个值“ something”,然后安全地沉入try之外。

您还可以强制try发生在sink内部:

try

您添加的put "start"; try { sink shell "./prog.sh" } put "end"; 块只是在阻止CATCH块返回try的返回值。

您可以重新排列它们,然后看到它仍然爆炸:

shell

处理此恕我直言的最好,最清晰的方法是自己检查shell的返回值,而不是让它沉没并抛出异常:

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