Zenity对话框点No/Cancel致脚本退出,终端执行正常的问题求助
解决Zenity对话框导致脚本直接退出的问题
我之前也踩过这个坑!核心原因大概率是你的脚本开启了set -e(也就是errexit模式)——这个选项会让脚本在任何命令返回非0状态时直接终止,而交互式Shell默认是关闭这个选项的,所以你直接在bash里跑代码没问题,但放到脚本里就会出现点击No/Cancel就直接退出的情况。
当你点击Zenity的No按钮,或者文件选择器的Cancel按钮时,Zenity会返回非0的退出码(比如1),如果脚本开了set -e,Bash会直接终止脚本,根本轮不到你把返回值存到变量里做判断。
下面给你几个可行的解决方案:
方案1:关闭set -e(最简单)
检查你的脚本开头,如果有set -e或者set -o errexit这一行,直接删掉它。这种方式适合不需要严格错误终止的脚本场景。
方案2:针对Zenity命令单独处理
如果必须保留set -e,可以让Zenity的非0返回不会触发脚本退出,有两种常用方式:
方式A:给Zenity命令加|| true
在每个Zenity命令后面追加|| true,这样不管Zenity返回什么,这条命令的整体返回值都是0,不会触发set -e的退出逻辑:
zenity --question --text "Start Firefox?" || true start_firefox=$? if [[ $start_firefox -eq 1 ]]; then # 启动Firefox的逻辑... fi zenity --question --text "Open Dolphin?" || true open_dolphin=$? if [[ $open_dolphin -eq 0 ]]; then # 给文件选择器也加上处理 directory=$(zenity --file-selection --directory || true) # 判断directory不为空再执行后续逻辑 if [[ -n $directory ]]; then # 打开Dolphin的逻辑... fi fi
方式B:用if直接包裹命令判断
Bash中,if语句会捕获命令的返回值,不会因为set -e而退出,你可以调整代码结构,直接用if判断Zenity的执行结果:
if zenity --question --text "Start Firefox?"; then # 用户点了Yes,这里对应返回码0,按你的原逻辑不执行启动 : # 空命令占位 else # 用户点了No,返回码1,执行启动Firefox的逻辑 # 启动Firefox... fi if zenity --question --text "Open Dolphin?"; then # 用户点Yes,执行文件选择 if directory=$(zenity --file-selection --directory); then # 用户选择了目录,打开Dolphin... fi fi
方案3:临时关闭errexit(适合保留全局set -e的场景)
如果你脚本大部分逻辑需要set -e,只有Zenity部分要临时关闭,可以先保存当前的errexit状态,执行完Zenity后再恢复:
# 保存当前的errexit设置 old_errexit=$(set +o | grep errexit) # 临时关闭errexit set +e zenity --question --text "Start Firefox?" start_firefox=$? if [[ $start_firefox -eq 1 ]]; then # 启动Firefox... fi # 恢复原来的errexit状态 $old_errexit
按照上面的方法调整后,脚本就不会因为点击No/Cancel直接退出了,你可以正常获取Zenity的返回值做判断。
内容的提问来源于stack exchange,提问作者Zenul_Abidin
相关产品推荐
相关产品推荐

