我有这个小脚本:
#!/bin/bash
for file in "$(ls | grep -v $0)";do
cat $file > "${file}-test"
done
在这个目录上:
total 40
-rwxr-xr-x 1 root root 783 Dec 11 09:19 appendToLog.sh
-rwxr-xr-x 1 root root 3995 Dec 11 13:22 con2dd.py
-rwxr-xr-x 1 root root 362 Dec 11 13:26 dd.py
-rw-r--r-- 1 root root 566 Dec 11 13:26 dd.pyc
-rw-r--r-- 1 root root 18558 Dec 25 11:24 moshe.log
-rw------- 1 root root 0 Dec 11 09:20 nohup.out
-rwxr-xr-x 1 root root 88 Dec 25 11:28 task.sh
-rwxr-xr-x 1 root root 560 Dec 11 10:33 test.py
没关系,我可以通过cp
实现这一点,我想知道为什么这正是产生这个文件:
-rw-r--r-- 1 root root 24912 Dec 25 11:28 appendToLog.sh?con2dd.py?dd.py?dd.pyc?moshe.log?nohup.out?task.sh?test.py-test
没有别的。
问题是解析ls
的输出是错误的(参见Why you shouldn't parse the output of ls(1),unix中的文件名几乎可以包含任何特殊字符,包括空格,换行符,逗号,管道符号。因为你在一个结构中引用了ls
的输出,你有一个所有文件的单个列表连接为"${file}-test"
值中的一个字符串,这完全不是您想要做的。
还要注意ls有时会伪装你的文件名数据(在我们的例子中,它将单词之间的\n
字符转换为?
问号(可能表示无法显示的字符)。
只需使用bash
中的glob扩展列出文件并对它们执行操作即可。
for f in *; do
[[ -e $f ]] || continue
...
done
也就是说,你可能在行尾有一些不可打印的字符(例如CRLF导入的rom Windows)
运行cat -A scriptname
它会显示脚本中的所有字符。然后,您可以转换为运行dos2unix scriptname
的类似unix的格式。