如何通过Java DefaultExecutor与CommandLine获取shell脚本的所有退出码
Java Commons Exec获取shell脚本全量退出码解决方案
问题根因
你遇到的异常是DefaultExecutor默认的退出码校验逻辑导致的:你通过setExitValue(0)仅指定了0为合法退出码,当脚本返回非0退出码时,框架会抛出ExecuteException(属于IOException的子类),不会直接返回退出码。
方案1:捕获ExecuteException提取退出码
适合只认可0为成功状态,需要单独处理其他异常退出码的场景。
注意需提前导入类:
import org.apache.commons.exec.ExecuteException;
修改后代码如下:
int iExitValue = 1; CommandLine cmd = CommandLine.parse("sh /Users/DpakG/scripts/do_Database_Operations.sh"); DefaultExecutor oDefaultExecutor = new DefaultExecutor(); oDefaultExecutor.setExitValue(0); try { iExitValue = oDefaultExecutor.execute(cmd); log.info("Script Exit Code: " + iExitValue); } catch (ExecuteException e) { // 从异常中获取脚本实际返回的退出码 iExitValue = e.getExitValue(); log.info("Script Exit Code with Error: " + iExitValue); // 这里可以根据不同退出码执行自定义逻辑 } catch (IOException e) { // 这类是真正的IO异常,比如脚本不存在、无执行权限、进程启动失败等,不属于脚本自身返回的退出码 log.error("IO error occurred when execute script: ", e); }
方案2:关闭退出码校验,直接返回所有退出码
如果你不需要框架帮你做退出码合法性校验,希望所有返回值都直接返回不抛异常,可以通过setExitValues(null)关闭校验逻辑:
int iExitValue = 1; CommandLine cmd = CommandLine.parse("sh /Users/DpakG/scripts/do_Database_Operations.sh"); DefaultExecutor oDefaultExecutor = new DefaultExecutor(); // 传入null表示不校验任何退出码,所有退出值都直接返回 oDefaultExecutor.setExitValues(null); try { iExitValue = oDefaultExecutor.execute(cmd); log.info("Script Exit Code: " + iExitValue); // 这里直接根据iExitValue的值处理自定义逻辑即可 } catch (IOException e) { // 仅捕获真正的IO错误,脚本自身的退出码不会走到这里 log.error("IO error occurred when execute script: ", e); }
常见退出码说明
- 127:通常表示系统找不到指定的命令/脚本,可检查脚本路径是否正确、是否有执行权限
- 128+N:表示脚本接收到信号N被中断,比如130对应Ctrl+C中断(信号2)
- 255:通常是脚本执行异常退出、权限不足或者返回码超出0-255范围被截断
内容的提问来源于stack exchange,提问作者DpakG
相关产品推荐
相关产品推荐

