NUL是C语言中的“字符串”(C语言中并没有字符串这种数据类型)结束标志字符。ASCII为0, 在数字系统中,处理边界的那些值往往是特别的。
UNIX中真正不能作为文件名和目录名的字符只有两个:/和NUL, 前者是因为它必需担当路径的分隔符功能,后者则是因为众多用来处理文件名/目录/路径的C请库函数都以它为字串结束的约定. 尽管乍看起来不可思议, 其它的一个非可见字符, 控制字符都是可以作为文件名的一部分的, 比如换行符. 可以用
touch $'a\nb'
试试($''要求3.0的bash)
所以NUL可以用来在文件名中混入了怪字符时确保万无一失.
假设有下面的文件名:
a very long file name.txt
这样的文件名在很多情况下由于空格被约定为命令行参数的分隔符的缘故,会被当作是5个不同的文件进行处理,比如
for i in *.txt; do echo $i; done
而
echo "a very long file name.txt" | read i
也只会让你的i被赋值a而已.
grep pattern $(find -iname '*.txt')
find -iname '*.txt' | xargs cvs add
这样的处理也是一样.
所幸,已经有一批命令行工具提供了参数来以NUL来区隔不同的参数了:
grep -z -l pattern *.txt
会在向标准输出发送文件名时, 以NUL结尾每个文件名.
find -print0
做相同的事
而 xargs 也有--null, 是作为对输入中以NUL分隔参数的呼应.
cpio 要处理的文件名也是来自标准输入, 参数也是 --null
但, 如果文件名是已经被保存在一个文件文件中, 每行一个呢?
cat filename.txt
却没有一个选项以NUL代替换行符, tr!
cat filename.txt | tr "\n" "\0" | xargs cvs add
阅读(1794) | 评论(0) | 转发(0) |