Bash使用xargs复制文件时最后一个参数带换行符是什么原因?
为什么xargs生成的最后一个参数带换行符
echo 命令默认会在输出内容的末尾追加一个换行符,你指定xargs的分隔符仅为空格(-d " ")时,xargs只会把空格识别为参数分割标记,不会处理末尾的换行符,这个换行符会被直接附加到最后一个参数.eclipse的末尾,最终变成你看到的'.eclipse'$'\n'的形式,自然找不到对应文件。
tr " " "\n"处理方案的优劣评估
这个方案只能解决你当前场景的问题,算不上最优,甚至存在明显通用性缺陷:
- 如果数组元素本身包含空格(比如存在名为
.my config的文件夹),空格会被tr替换成换行,直接把一个合法的文件名拆成两个无效参数,导致执行出错。 - 你给出的示例能正常运行,只是因为当前数组的所有元素都不含空格,本质上还是没有解决参数含特殊字符的通用性问题。
更稳妥的无歧义实现方案
如果使用Bash环境,不需要通过管道传递数组,直接遍历数组执行复制更稳妥,不会出现特殊字符解析问题:
folders_array=(.mozilla .thunderbird .ssh .eclipse) for dir in "${folders_array[@]}"; do sudo cp -r "$dir" /home/nebukadnexa/ done
如果一定要搭配xargs使用,最安全的是用NUL(空字符)作为分隔符,完全规避文件名含空格、换行、特殊字符的问题:
printf "%s\0" "${folders_array[@]}" | xargs -0 -I _ sudo cp -r _ /home/nebukadnexa/
内容的提问来源于stack exchange,提问作者von spotz
相关产品推荐
相关产品推荐

