反引号用于文件名场景下的异常行为技术问询
问题分析与解决方案
兄弟,你遇到的这个问题根源很简单——ls的颜色输出把ANSI转义字符混进了文件名里!
问题原因拆解
当你用反引号捕获ls file*的输出时,如果你的终端默认开启了颜色高亮(绝大多数Linux/macOS终端都会这么配置),ls为了给文件名添色,会在输出里插入一堆ANSI颜色控制序列(就是你看到的\033[00m这类字符)。这些字符会被当成字符串的一部分赋值给idx变量:
- 用
echo $idx时,终端会把这些转义字符解析成颜色控制命令,所以你看到的是正常文件名; - 但把
$idx用作文件名时,这些转义字符就实实在在变成了文件名的一部分,所以ls output会显示那些奇怪的乱码。
另外,你原来的循环语法也有小问题:do前面必须加分号或者换行,不然shell会直接报错。
正确的写法
直接用shell的通配符展开来遍历文件,完全避开ls的坑:
# 多行写法(更易读) for idx in file*; do cp "$idx" ./output/"$idx" done
或者一行搞定:
for idx in file*; do cp "$idx" ./output/"$idx"; done
为什么这能解决问题?
- shell通配符更可靠:
file*会让shell直接展开成当前目录下所有以file开头的文件名,完全不会引入任何额外的格式字符; - 双引号包裹变量:用
"$idx"可以避免文件名里有空格、特殊字符时出现意外(虽然你现在的文件名没有,但养成这个好习惯能避免很多后续问题)。
额外提醒
永远不要用ls的输出作为循环的输入!shell本身的通配符展开比ls的输出靠谱得多,而且不会引入颜色、换行这类干扰性的格式字符。如果实在要处理ls的输出,得先关掉颜色(比如ls --color=never file*),但这完全是多此一举——直接用通配符才是最优解。
内容的提问来源于stack exchange,提问作者Yuma Nakamura
相关产品推荐
相关产品推荐

