shell 脚本未将空格用作参数分隔符(有人可以解释一下这个小文件差异吗?)

Che*_*tar 10 diff shell-script arguments hex

简短版本(TL;DR)

\n

我有 2 个小的单行文件,看起来相同:

\n
$ cat f1 f2\n./cconv.sh 100 EUR\xc2\xa0USD\n./cconv.sh 100 EUR USD\n
Run Code Online (Sandbox Code Playgroud)\n

但它们不是,大小有 1 个字节的差异:

\n
$ ls -l f1 f2\n(...) 24 oct.  30 16:19 f1\n(...) 23 oct.  30 16:19 f2\n\n$ diff f1 f2\n1c1\n< ./cconv.sh 100 EUR\xc2\xa0USD\n---\n> ./cconv.sh 100 EUR USD\n
Run Code Online (Sandbox Code Playgroud)\n

我曾经dhex计算过十六进制的差异。看起来 :

\n
    \n
  • f1结束于c2 a0 55 53 44 0a
  • \n
  • f2结束于 20 55 53 44 0a
  • \n
\n

有人知道这里发生了什么事吗?有什么区别,更重要的是,它来自哪里?以下是包含这两个文件的 zip 文件的链接以及结果的屏幕截图dhex

\n

长版(附加说明)

\n

这两个文件是我的~/.bash_history file.

\n

我注意到我的贝壳有一种非常奇怪的行为。采用以下非常基本的脚本:

\n
#!/bin/sh\necho $#\necho "$1"\necho "$2"\necho "$3"\nexit 0\n
Run Code Online (Sandbox Code Playgroud)\n

在某些情况下(但哪些???),它不将空格作为参数分隔符:

\n
$ ./cconv.sh 100 EUR\xc2\xa0USD\n2\n100\nEUR\xc2\xa0USD\n
Run Code Online (Sandbox Code Playgroud)\n

但有时它会像预期的那样工作:

\n
$ ./cconv.sh 100 EUR\xc2\xa0USD\n3\n100\nEUR\nUSD\n
Run Code Online (Sandbox Code Playgroud)\n

这让我发疯!我花了几个小时试图弄清楚发生了什么事。以下是我尝试缩小范围的一些测试:

\n
    \n
  • 我使用装有 Debian 11、Gnome 3.38 的笔记本电脑。但我碰巧也有一个具有完全相同操作系统(D11、G3.38)的虚拟机,并且在虚拟机中一切正常。很明显,我一定对我的裸机笔记本电脑做了什么,它才会出现异常行为。但什么???
  • \n
  • 我注意到该问题仅发生在图形会话中。如果我打开一个 tty (Ctrl+Alt+F n ),它工作正常
  • \n
  • 我怀疑我的终端模拟器。但不同模拟器中的行为是相同的(我尝试了 Gnome Terminal、Terminator 和 Konsole,结果相同)
  • \n
  • 我怀疑是外壳。但 Bash 或 Dash 的行为是相同的
  • \n
  • 我禁用了我能想到的所有自定义:\n
      \n
    • 我暂时删除了/etc/bashrc, /etc/profile,/etc/inputrc/etc/rc.local
    • \n
    • 我暂时删除了~/.bashrc~/.profile并且~/.inputrc
    • \n
    • 我禁用了所有 Gnome Shell 扩展
    • \n
    \n
  • \n
  • 我什至怀疑键盘的问题,就插了一个USB键盘。相同的结果。
  • \n
\n

我真的很困惑,不知道发生了什么。我终于注意到 中的 2 个命令之间存在细微差别~/.bash_history:一个来自我的 Gnome 会话,另一个来自我的 tty 会话。显然是有区别的,但具体是什么,原因可能是什么?

\n

ilk*_*chu 21

c2 a0是不间断空格字符的 UTF-8 编码。它通常看起来像一个常规空格,但 shell 不会将其识别为空白。

\n

在一些键盘映射中,类似AltGr+SpaceOption+ 的东西Space会产生不间断的空格。AltGr如果您的键盘映射在或后面还有管道字符Option,这会很有趣,这样可以更轻松地键入|<nbsp>而不是|<sp>,从而给出如下错误:

\n
$ echo foo |\xc2\xa0grep .\nbash: \xc2\xa0grep: command not found\n
Run Code Online (Sandbox Code Playgroud)\n

(我认为 SE 将 nbsp 折叠到常规空间,因此如果从此处复制粘贴,您可能不会收到错误。)

\n

如果您从其他工具复制并粘贴参数,您可能会从那里得到奇怪的格式,但这取决于程序。

\n

有关不生成字符的一些解决方案,请参阅在 shell 中处理 nbsp 字符。

\n

  • 谢谢 !谜团已揭开 !我确实在 Gnome 中配置了 Shift+Space 来输入 NBSP。看来,在输入“EUR USD”时,我按住了 Shift 键,因此我得到了 NBSP 而不是空格。解决方案是使用另一个 NBSP 修饰键,而不是 Shift。 (2认同)
  • 它在 Gnome 中默认是禁用的,但我特意激活了它,因为在某些情况下我需要它。我只是没有想到副作用。我认为 Shift+AltGr+Space 是一个很好的折衷方案。它可以轻松访问 NBSP,且没有任何副作用。 (2认同)