安全存入shell数组应使用mapfile -t arr
要把命令执行的多行结果安全存入 Shell 数组,核心是避免因空格、制表符、换行符或特殊字符(比如含空格的文件名)导致分割错误。直接用
arr=($(cmd))看似简单,但非常危险——它依赖默认的IFS(空格/制表符/换行符),会把一个带空格的路径如/home/user/my file.txt拆成两个数组元素。推荐方法:用
mapfile(或readarray)逐行读取这是最简洁、安全、现代的方式(要求 Bash ≥ 4.0,绝大多数 Linux 发行版默认满足):
mapfile -t arr-t自动去掉每行末尾的换行符是进程替换,确保输出按行完整传递,不经过管道子 shell 丢失变量作用域- 示例:把所有
.mkv文件路径安全存入数组mapfile -t mkv_files兼容旧版 Bash 或需处理含换行符的文件名时:用
find -print0+mapfile -d ''当文件名本身可能含换行符(极少见但理论上存在),必须用 null 字符分隔:
mapfile -d '' -t safe_arr-d ''表示以 ASCII NUL(\0)为分隔符- 注意:
-print0和-d ''必须配对使用,否则行为未定义不用
mapfile的备选:手动控制IFS+ 命令替换适用于较老环境,但仅限输出**确定不含空格/制表符**的场景(如纯数字、纯标识符):
- 临时将
IFS设为换行符,再赋值:old_ifs=$IFS; IFS=$'\n'; arr=($(your_command)); IFS=$old_ifs- 必须保存并恢复
IFS,否则会影响后续命令- ⚠️ 不推荐用于文件路径、用户输入等不可控内容
验证和使用数组
存好后,用标准语法访问:
- 元素个数:
echo ${#arr[@]}- 遍历所有项(引号必不可少):
for item in "${arr[@]}"; do echo "→ $item"; done- 打印第 0 个元素:
echo "${arr[0]}"












