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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5381467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:18:23  来源:igfitidea点击:

bash test yields "echo: command not found"

bashtestingcommandecho

提问by Christian

Ok, something funny happens all of a sudden. This test

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

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

used to work fine (for every entry in the file liste.txt try to find a corresponding directory, print the name if not found) and used to yield the names of directories missing. Now this command yields

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

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

I've tried using [[...]] and "test" instead of "[ ..]" but to no avail.

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

Any ideas what might have happened with my beloved bash while I wasn't looking :) ?

有什么想法在我不看的时候我心爱的 bash 会发生什么:)?

Thanks, Christian.

谢谢,克里斯蒂安。

Edit (set -x output):

编辑(设置 -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 ']'
+ $'20echo' THE_REBOUND
+ '[' -x /usr/lib/command-not-found ']'
+ /usr/bin/python /usr/lib/command-not-found -- $'20echo'
?echo: command not found
+ return 127
(...)

回答by Mikel

If you look closely, you will see it's printing:

如果仔细观察,您会看到它正在打印:

 echo: command not found

with a leading space, rather than:

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

echo: command not found

set -xmakes this much clearer when it prints:

set -x打印时使这一点更加清晰:

$'20echo' THE_REBOUND

0302 0240is octal UTF-8 for a non-breaking space.

0302 0240是八进制 UTF-8,用于不间断空格

Try deleting the space between |and echoand type a normal space.

尝试删除之间的空间|echo并键入一个正常的空间。



Chances are, the file was edited on a Mac, where a non-breaking space can be entered accidentally if you press Optionat the same time as Space.

机会是,该文件是编辑的Mac上,在那里,如果你按一个非换空间可以小心输入上Option在同一时间Space

If you're using Vim, you can make non-breaking spaces more obvious by using the listchars option. For example:

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

set listchars+=nbsp:% list

See Making Vim highlight suspicious charactersfor some more ideas.

有关更多想法,请参阅使 Vim 突出显示可疑字符

On Linux, non-breaking space is either ComposeSpaceSpaceor Ctrl+Shift+ua0, so you're probably not going to type that by accident.

在Linux中,非换空间或者是ComposeSpaceSpaceCtrl+ Shift+ ua0,所以你可能不会被意外键入。



For anyone interested, it's possible to manually convert the octal bytes to UTF-8 using the UTF-8 tablefrom the UTF-8 Wikipedia article.

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

But by far the easiest way I found was using Python:

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

>>> import unicodedata
>>> unicodedata.name('20'.decode('utf-8'))
'NO-BREAK SPACE'

回答by l0b0

Edit: The code below is still fine, but the issue is probably in $'\302\240echo': There seems to be unknown charactersin your text file. Try removing the couple characters before echo and then typing them again.

编辑:下面的代码仍然很好,但问题可能出在$'\302\240echo':您的文本文件中似乎有未知字符。尝试在 echo 之前删除几个字符,然后再次输入它们。

It could well be a quotingissue. Also, you could save some time by avoiding the useless use of cat:

这很可能是一个引用问题。此外,您可以通过避免无用的使用cat来节省一些时间:

while IFS= read -r; do [ -f "/mnt/usb/lsdvd.xml/$REPLY" ] || echo "$REPLY"; done < /mnt/usb/liste.txt

回答by bta

What happens when you run simply:

当你简单地运行时会发生什么:

for i in `cat /mnt/usb/liste.txt `; do
    echo $i
done

For one thing, do you notice anything abnormal about the filenames (spaces, newlines, special characters, etc)? If so, you will need to quote the filename to keep the shell from mis-interpreting it.

一方面,您是否注意到文件名(空格、换行符、特殊字符等)有任何异常?如果是这样,您将需要引用文件名以防止 shell 错误解释它。

Also, try using a normal ifstatement instead of the logical OR:

另外,尝试使用普通if语句而不是逻辑 OR:

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

回答by user unknown

Works for me:

对我有用:

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

Just my own filenames, directories, and suggested construct $(...) instead of backticks, and with < instead of cat.

只是我自己的文件名、目录和建议构造 $(...) 而不是反引号,并用 < 代替 cat。

Maybe a dos/windows linefeed in your list? View it with less.

也许你的列表中有一个 dos/windows 换行符?用 来查看less