管道符后的命令被认为是带有一个空格前缀的命令。

11

有时在我的终端(Ubuntu)上,当我输入:

ls | grep toto

我收到了这个错误信息:

 grep: command not found*

注意到Shell在grep前加了一个空格。这是如何可能的?


1
你能可靠地重现它吗?ls | grep something 是命令行上唯一的东西吗?这看起来像是引号中有一个空格,需要转义。 - rbp
这是一种特殊的空格吗?不间断空格、窄空格等。 - knittl
如果我执行 ls | less,会得到 less: command not found 的错误提示。 - user2854544
当错误发生时,echo $PATH与未发生错误时相同。 - user2854544
1
@user2854544,我只能通过 ls |\ grep toto 来重现该错误。你的终端是否可能发送了一些非实际空格,比如某些类似空格的Unicode字符 - ghoti
显示剩余4条评论
2个回答

28

<查看您原始问题的源代码>

<pre style="width:650px; white-space:pre-wrap">Sometimes on my terminal (Ubuntu) when I type :

ls |&#160;grep toto
感谢您复制并粘贴实际行!(但是您没有复制并粘贴错误消息,你真不好!)看到问题了吗?在竖杠符号后面有一个不间断空格。Shell 只能理解 ASCII 字符;所有非 ASCII 字符包括 U+00A0 不间断空格都会被视为单词构成部分,因此不间断空格会被视为命令名称位置的一部分。
您可能正在使用需要按住 AltGr 键才能输入 | 的键盘布局。确保释放 AltGr 修改器,以免意外键入 AltGr+Space 而不是 Space。请注意,您不需要在那里输入空格,如果这样更容易操作,可以键入 ls |grep toto

可以说,Bash的解析器应该将非断空格规范化为普通空格。 - tripleee
@tripleee 这会很棘手:bash 必须假设字符串的编码与区域设置指定的编码匹配,但实际上并不总是这样,这会破坏一些现有的应用程序。 - Gilles 'SO- stop being evil'
非常感谢您的回答。直到现在我才意识到这不是一个 bug。 - ling
我的问题是,记录一下,实际上是 Shift + Space(我的管道字符需要 shift)。 - jcuenod

6
为了补充Gilles的回答,您可以通过在Ubuntu / Gnome中在键盘布局设置中将不间断空格字符替换为普通空格来禁用此行为。
设置 - > 键盘 - > 布局 - > 选项,然后选择“使用空格键输入不间断空格字符”,并将其设置为:“任何级别的普通空格”。
或者从命令行。
setxkbmap -option "nbsp:none"

我在http://my.opera.com/nicomen/blog/unrecognized-character-xc2上找到了这个解决方法。

在使用花括号编写Perl脚本或在Python中使用哈希符号进行注释并跟随空格时,法语键盘也会遇到此问题,这也很令人烦恼。


还有一个 https://dev59.com/_Woy5IYBdhLWcg3wN7e8,其中有一个不依赖于 X 的好的替代方法。 - tripleee

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