我必须运行一个退出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
块呢?
答案 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";