GNU/Linux Bash脚本添加图形界面后执行异常,cd命令失效问题排查
问题定位与修复方案
我一眼就瞅到问题所在了——你输入的~/Destination这类带~的路径没有被Shell正确展开!
为啥会这样?
当你在zenity弹窗里输入~/Destination时,它只是被当成一个普通字符串传给了getList.sh。Bash只有在命令行直接输入路径时才会自动把~换成你的家目录(比如/home/yourname/Destination),但对于脚本参数里的~,它不会主动去解析。所以cd $DestinationPath实际上是在找一个叫~/Destination的字面目录,这肯定找不到啊!
怎么修复?
有两种简单的办法,选哪种都行:
办法1:在图形界面脚本里先展开路径
在调用getList.sh之前,把获取到的路径里的~展开成实际路径。同时一定要给参数加双引号(不然路径里有空格会直接崩):
修改你的图形界面脚本(menu.sh):
#! /bin/bash SourcePath=$(zenity --entry --text "Enter your source path" --title "sourcepath" --entry-text=""); DestinationPath=$(zenity --entry --text "Enter your destination path" --title "destination path" --entry-text=""); DestinationFileName=$(zenity --entry --text "Enter your destination file name" --title "destination file name" --entry-text=""); ask=`zenity --list --title="Choose your Option" --column="0" "1" "2" "3" --width=100 --height=300 --hide-header` # 重点:展开路径里的~ SourcePath=$(eval echo "$SourcePath") DestinationPath=$(eval echo "$DestinationPath") # 调用脚本时给所有参数加双引号 if [ "$ask" == "1" ]; then bash ./getList.sh "$SourcePath" "$DestinationPath" "$DestinationFileName" "$ask" fi if [ "$ask" == "2" ]; then bash ./getList.sh "$SourcePath" "$DestinationPath" "$DestinationFileName" "$ask" fi if [ "$ask" == "3" ]; then SearchFile=$(zenity --entry --text "Enter your search term" --title "search term" --entry-text=""); # 搜索词如果带~也可以展开 SearchFile=$(eval echo "$SearchFile") bash ./getList.sh "$SourcePath" "$DestinationPath" "$DestinationFileName" "$ask" "$SearchFile" fi
办法2:在getList.sh内部处理路径展开
如果你不想改界面脚本,也可以在getList.sh里直接处理参数:
#! /bin/bash # 替换原来的参数赋值,先展开~ SourcePath=$(eval echo "$1") DestinationPath=$(eval echo "$2") DestinationFileName=$(eval echo "$3") Option=$4 # Option 1的代码也要加双引号,并且检查目录是否存在 if [ "$Option" = 1 ] then # 先检查目标目录是否存在,避免cd报错 if [ ! -d "$DestinationPath" ]; then echo "Error: 目标目录 $DestinationPath 不存在!" exit 1 fi # cd失败就直接退出,别往下跑了 cd "$DestinationPath" || exit 1 # 这里你原来用的$PathDate没定义,应该是$DestinationFileName吧? ls -1Rasl "$SourcePath" > "$DestinationFileName" # ... 其他代码保持不变 fi
额外提醒几个小坑
- 变量未定义:你
getList.sh里的$PathDate根本没定义,应该是打错了,换成$DestinationFileName才对! - 空格问题:所有涉及路径的变量都要用双引号包起来,不然路径里有空格的话,Shell会把它拆成多个参数,直接乱套。
- 错误提示:可以加个目录检查,给用户更友好的报错,而不是干巴巴的“找不到目录”。
这样修改完,你的脚本应该就能正常工作啦!
内容的提问来源于stack exchange,提问作者Mooon




