bash测试产生“echo:command not found”

时间:2011-03-21 17:44:00

标签: bash testing command echo

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

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

用于正常工作(对于文件中的每个条目,liste.txt尝试查找相应的目录,如果未找到则打印名称)并用于生成缺少的目录名称。现在这个命令产生

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

我尝试使用[[...]]和“test”而不是“[..]”,但无济于事。

在我不看的时候,我心爱的bash可能发生了什么想法:)?

谢谢,  基督教。

编辑(设置-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
(...)

4 个答案:

答案 0 :(得分:17)

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

 echo: command not found

有一个领先的空间,而不是:

echo: command not found

set -x在打印时更加清晰:

$'\302\240echo' THE_REBOUND

0302 0240non-breaking space的八进制UTF-8。

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


有可能,该文件是在Mac上编辑的,如果您在 Space 的同时按 Option ,则可能会意外输入不间断的空格。 / p>

如果您正在使用Vim,则可以使用listchars option使非破坏空间更明显。例如:

set listchars+=nbsp:% list

有关更多提示,请参阅Making Vim highlight suspicious characters

在Linux上,不间断空格要么是 Compose Space Space Ctrl + Shift + u a 0 ,所以你可能不会意外输入。


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

但到目前为止,我发现最简单的方法是使用Python:

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

答案 1 :(得分:3)

修改:下面的代码仍然正常,但问题可能在$'\302\240echo':您的文本文件中似乎有未知字符。尝试在回显之前删除几个字符,然后再次键入它们。

很可能是引用问题。此外,您可以通过避免useless use of cat

来节省一些时间
while IFS= read -r; do [ -f "/mnt/usb/lsdvd.xml/$REPLY" ] || echo "$REPLY"; done < /mnt/usb/liste.txt

答案 2 :(得分:1)

当你简单地跑步时会发生什么:

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

答案 3 :(得分:0)

适合我:

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

只是我自己的文件名,目录和建议构造$(...)而不是反引号,并使用&lt;而不是猫。

也许你的列表中有dos / windows换行符?使用less查看。