Bash含空格路径目录列表变量失效问题及修复方法咨询
Bash带空格路径的通配符数组初始化问题
现象
以下写法可以正常获取目标目录下的所有文件:
List=(/home/MyUserName/Desktop/Folder\ With\ Spaces/*) echo "${List[@]}"
但下面两种写法会失效(无法正确识别带空格的路径,通配符*也不会展开):
# 写法1:双引号赋值后转数组 List="/home/MyUserName/Desktop/Folder\ With\ Spaces/*" List=($List) echo $List
# 写法2:单引号赋值后转数组 List='/home/MyUserName/Desktop/Folder\ With\ Spaces/*' List=($List) echo $List
失效原因
核心问题是shell在不同阶段的解析规则差异:
- 正确写法中,数组初始化时的路径直接被shell解析:反斜杠是shell的转义符,用来标记空格是路径的一部分(而非参数分隔符),同时
*会被自动展开成目录下的所有文件。 - 错误写法中:
- 双引号/单引号赋值时,反斜杠会被保留成字符串的一部分(双引号里反斜杠仅对特定字符生效,这里的空格不在其中;单引号会完全保留所有字符),不再是转义符。
- 执行
List=($List)时,shell会对变量值做分词处理:把字符串中的空格(包括反斜杠后的空格)当成参数分隔符,导致路径被拆成多个数组元素;同时*作为普通字符串存在,不会被展开成通配符。
修复方案
方案1:使用eval重新解析字符串(适合可信输入场景)
如果生成的路径字符串带反斜杠转义空格,用eval让shell重新解析转义符和通配符:
# 假设此字符串由程序自动生成 List_str="/home/MyUserName/Desktop/Folder\ With\ Spaces/*" eval "List=($List_str)" # 正确输出所有数组元素,必须加@和双引号 echo "${List[@]}"
注意:eval会执行字符串中的任意shell命令,如果输入不可信,存在安全风险。
方案2:用compgen+readarray(更安全)
如果程序生成的字符串是直接带空格的路径(无需反斜杠),可以用compgen处理通配符,再用readarray以空字符分隔读取,避免分词问题:
# 程序生成的原始路径(无反斜杠) List_str="/home/MyUserName/Desktop/Folder With Spaces/*" # 用compgen处理通配符,readarray以空字符分隔存入数组 readarray -d '' List < <(compgen -G "$List_str") echo "${List[@]}"
如果生成的字符串带反斜杠,先去掉反斜杠再处理:
List_str="/home/MyUserName/Desktop/Folder\ With\ Spaces/*" # 移除反斜杠 List_str_clean=$(echo "$List_str" | sed 's/\\//g') readarray -d '' List < <(compgen -G "$List_str_clean") echo "${List[@]}"
注意:输出数组时必须用
"${List[@]}",而不是$List——后者只会输出数组的第一个元素,且无法保留元素中的空格。
内容的提问来源于stack exchange,提问作者Steam Ranger
相关产品推荐
相关产品推荐

