Bash中检测含空格文件存在时为何需额外单引号?
问题分析与解决
先还原你的场景,结合描述推测你的代码大概是这样的:
# 存在问题的检测函数 backup_check() { # 错误地将测试命令拼为字符串后执行 local check_cmd="[ -e $1 ]" if eval "$check_cmd"; then echo "路径存在" else echo "路径不存在" fi } # 测试用的正常函数 normal_check() { if [ -e "$1" ]; then echo "路径存在" else echo "路径不存在" fi } # 带空格的路径变量 tobackup="/home/user/My Documents/file.txt"
异常原因
当你调用backup_check "$tobackup"时,$1会被展开为/home/user/My Documents/file.txt,此时check_cmd变成[ -e /home/user/My Documents/file.txt ]——这里的空格会把路径拆成三个独立参数:/home/user/My、Documents/file.txt,导致[命令因参数数量不合法报错,自然无法正确识别路径。
而当你用backup_check '"$tobackup"'调用时,$1是"$tobackup",check_cmd变成[ -e "$tobackup" ],执行eval时会先展开$tobackup得到带空格的路径,同时引号会把整个路径包裹成一个完整参数,[命令就能正确识别,所以检测正常。
你的测试函数normal_check直接用[ -e "$1" ],这里的"$1"会把传入的带空格路径完整作为一个参数传递给[命令,不需要额外引号嵌套,因此工作正常。
正确写法
根本问题是不要用字符串拼接+eval的方式处理命令参数,直接在函数里使用参数引用即可:
fixed_backup_check() { if [ -e "$1" ]; then echo "路径存在" else echo "路径不存在" fi } # 调用时正常传参即可 fixed_backup_check "$tobackup"
如果函数逻辑必须用到动态生成的命令(比如复杂条件拼接),建议用数组保存命令和参数,避免eval带来的参数拆分问题:
array_backup_check() { local check_args=([ -e "$1" ]) if "${check_args[@]}"; then echo "路径存在" else echo "路径不存在" fi }
内容的提问来源于stack exchange,提问作者WesternGun
相关产品推荐
相关产品推荐

