Bash测试出现"echo: command not found"错误。

19

好的,突然发生了一些有趣的事情。这个测试

for i in `cat /mnt/usb/liste.txt `; do [ -f /mnt/usb/lsdvd.xml/$i ] || echo $i; done

曾经能够正常工作(对于list.txt文件中的每个条目,尝试查找相应的目录,如果未找到则打印名称),并且曾经会显示缺失目录的名称。现在这个命令却产生了以下结果

 echo: command not found
 echo: command not found
 echo: command not found
(...)

我尝试使用[[...]]和"test"代替"[..]",但都没有用。

有什么想法,可能是在我不注意的时候发生了什么问题:)

谢谢, 基督徒。

编辑(设置 -x 输出):

(...)
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_GHOST_WRITER.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_IMAGINARIUM_OF_DOCTOR_PARNASSUS.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_INFORMANT.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_INTERNATIONAL.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_MEN_WHO_STARE_AT_GOATS.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_OTHER_MAN.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_QUEEN.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_READER.lsdvd.xml ']'
+ for i in '`cat /mnt/usb/liste.txt`'
+ '[' -f /mnt/usb/lsdvd.xml/THE_REBOUND.lsdvd.xml ']'
+ $'\302\240echo' THE_REBOUND
+ '[' -x /usr/lib/command-not-found ']'
+ /usr/bin/python /usr/lib/command-not-found -- $'\302\240echo'
 echo: command not found
+ return 127
(...)

你尝试过用双引号包裹 $i 吗? - Yannick Loiseau
如果你将行尾替换为 echooooo $1; done,会出现错误 echooooo: command not found 吗?当我在 bash 命令提示符下输入垃圾时,就会出现“command not found”错误。如果你将其替换为 /bin/echo 呢? - David Yaw
1
在脚本顶部添加set -x,并观察 shell 执行的每个命令。 - bobbogo
我的发现:双引号 $i:无效,同样的错误。echoooo:找不到命令。 - Christian
4个回答

38

仔细观察,你会发现它正在打印:

 echo: command not found

以前导空格开头,而不是:

echo: command not found

set -x在打印时会使这个过程更加清晰:

$'\302\240echo' THE_REBOUND

0302 0240 是八进制 UTF-8编码的一个不换行空格

尝试删除 |echo之间的空格,然后输入普通空格。


很可能该文件在Mac上进行了编辑,如果您同时按下 OptionSpace,可能会意外输入不换行空格。

如果您使用Vim,可以使用listchars选项使不换行空格更加明显。例如:

set listchars+=nbsp:% list

查看 Making Vim highlight suspicious characters 了解更多相关信息。

在 Linux 上,不间断空格通常为 Compose Space SpaceCtrl+Shift+ua0,因此您可能不会意外输入它。


对于任何有兴趣的人,可以手动使用UTF-8维基百科文章中的UTF-8表将八进制字节转换为UTF-8。

但我发现迄今为止最简单的方法是使用Python:

>>> import unicodedata
>>> unicodedata.name('\302\240'.decode('utf-8'))
'NO-BREAK SPACE'

3
编辑:下面的代码仍然可以使用,但问题可能出在$'\302\240echo'中:您的文本文件中似乎有未知字符。尝试删除echo前面的一对字符,然后重新输入它们。
这可能是引用问题。此外,您可以通过避免不必要地使用cat来节省时间。
while IFS= read -r; do [ -f "/mnt/usb/lsdvd.xml/$REPLY" ] || echo "$REPLY"; done < /mnt/usb/liste.txt

2
当您运行简单命令时会发生什么:
for i in `cat /mnt/usb/liste.txt `; do
    echo $i
done

首先,你有没有注意到文件名是否存在异常(空格、换行符、特殊字符等)?如果存在异常,你需要用引号引起来,以防止shell误解它。

另外,尝试使用普通的if语句代替逻辑OR:

for i in `cat /mnt/usb/liste.txt `; do
    if [ ! -f /mnt/usb/lsdvd.xml/$i ]; then
        echo $i
    fi
done

简单的for-echo-done循环运行良好,文件名也没有什么异常。实际上,它们非常好:没有空格,甚至没有数字。 - Christian
for-if-then-fi-done循环运行良好,所以问题肯定出在||和奇怪的未加引号的字符串上,但我似乎找不到文件及其名称方面的任何异常。 - Christian

0

对我来说可行:

for f in $(< d2.lst); do [ -f ./d2/$f ] || echo $f ; done

只是我的文件名、目录和建议使用 $(...) 而不是反引号,并且使用 < 而不是 cat。

也许在您的列表中有一个 dos/windows 换行符?使用 less 查看它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接