Bash Dialog GUI程序问题:进入子目录后无法返回原目录
问题分析与修复
问题根源
你遇到的问题核心是直接修改了当前Shell的工作目录:当执行cd $file进入ANIMALS目录后,display_folders的循环会在新目录下重新执行,所以会显示ANIMALS下的OTHERS子目录;退出时的状态码1是因为后续流程在新目录中运行,触发了不同的退出分支。
修复方案
要实现「执行完目录内操作后回到原目录」的需求,有两种简单可靠的方式:
方式1:用pushd/popd管理目录栈
pushd会将当前目录压入栈并切换到目标目录,popd会弹出栈顶目录切回去,完美匹配你的需求。修改display_folders中的目录切换逻辑:
case "$file" in *) pushd "$file" > /dev/null # 压入原目录,切换到目标目录,屏蔽输出 display_result "$file" popd > /dev/null # 切回原目录,屏蔽输出 ;; esac
方式2:在子Shell中执行目录内操作
子Shell的目录切换不会影响父Shell,执行完子Shell后自动回到原目录:
case "$file" in *) (cd "$file"; display_result "$file") # 括号开启子Shell,内部cd不影响外部 ;; esac
额外修复:Dialog命令语法错误
原代码中display_folders里的dialog命令重定向不完整,应该和display_result中的写法一致,修改后的完整dialog行:
file=$(dialog --title "List directory" --cancel-label "Exit" --no-tags --menu "Please choose one folder: " 10 40 0 "${w[@]}" 3>&2 2>&1 1>&3)
完整修改后的display_folders函数
display_folders() { while true; do let count=0 #define counting variable w=() #define working array while read -r line; do #process file by file let count=$count+1 w+=("$line" "$line") done < <(ls -d */) # 修复Dialog重定向语法 file=$(dialog --title "List directory" --cancel-label "Exit" --no-tags --menu "Please choose one folder: " 10 40 0 "${w[@]}" 3>&2 2>&1 1>&3) #clear exit_status=$? echo $exit_status case $exit_status in 1) echo "Program terminated" exit ;; 255) echo "Program aborted" exit 1 ;; esac echo "this is $file" case "$file" in *) # 用pushd/popd的方式,二选一即可 pushd "$file" > /dev/null display_result "$file" popd > /dev/null # 或者用子Shell方式 # (cd "$file"; display_result "$file") ;; esac done }
效果验证
修改后,选中ANIMALS目录进入操作菜单,执行完操作退出菜单时,会自动回到包含ANIMALS的原目录,display_folders会重新显示原目录下的子列表,不会进入OTHERS目录的循环。
内容的提问来源于stack exchange,提问作者MBI
相关产品推荐
相关产品推荐

