ls命令输出是否标准化?能否完美解析为文件名数组?
解析文件名列表:别用ls的输出来做!
哥们,你踩了一个很多人都掉过的shell编程陷阱——ls的输出完全不适合用来解析文件名数组,原因如下:
1. ls的输出根本没有标准化
ls的输出格式会根据很多因素变化:
- 终端宽度不同,ls会自动调整列数,用空格或制表符分隔文件名;
- 如果设置了
LS_COLORS环境变量,ls还会输出颜色控制字符; - 文件名包含空格、制表符甚至换行符(虽然少见但完全合法)时,ls会把这些字符当成普通内容输出,导致你无法区分“分隔符”和“文件名本身的字符”。
比如如果有个文件名是std test.h,ls输出里的空格会让你误以为是两个文件名,这直接就错了。
2. 完美解析文件名的正确方法
方法一:直接让shell传递文件名作为命令行参数
这是最可靠的方式,完全避开管道解析的问题。把你的命令改成:
./distribuer 3 /usr/include/std*.h
shell会自动展开通配符,把每个完整的文件名作为独立的命令行参数传给你的程序,不管文件名里有什么特殊字符,程序都能通过argv数组正确获取到每个文件名。
方法二:用空字符分隔的输出(如果必须用管道)
如果你确实需要通过管道传递文件名列表,一定要用空字符作为分隔符——因为POSIX标准规定文件名不能包含空字符,这是唯一安全的分隔方式。
比如用find命令替代ls:
find /usr/include -name 'std*.h' -print0 | ./distribuer 3
然后你的程序在读取标准输入时,要以\0(空字符)作为分隔符来分割数据,这样就能准确得到每个文件名,不管里面有空格、制表符还是换行符。
总结
永远不要尝试解析ls的输出来获取文件名,这是一个公认的反模式。优先用shell通配符传递参数,管道场景则用空字符分隔的输出,这才是处理文件名列表的完美方案。
内容的提问来源于stack exchange,提问作者Pop Flamingo
相关产品推荐
相关产品推荐

