后面的嘀嗒声搞乱了命令的输出

时间:2017-07-25 20:35:57

标签: bash msys2

例如:

ipconfig > temp
cat temp

产生正确的结果(来自ipconfig的所有输出)。

然而:

ipconfig > temp
echo `cat temp`

产生非常错误的结果:

Connection-specific DNS Suffix . :: Media disconnected2A612}:%62

就是这样,没有更多的东西正在打印,这显然是错误的,因为如果我在编辑器中打开temp我可以清楚地看到正确的输出。

1 个答案:

答案 0 :(得分:1)

要使其有效,请将echo `cat temp`更改为echo "`cat temp`"

您遇到此问题有几个原因:

不带引号的命令替换

echo `cat temp`是一种不带引号的命令替换形式,它将导致单词拆分(以及通配符)。

包含换行符\n的空格被bash视为分隔符,因此它会将由空格分隔的任何文本处理为数组中的元素,然后传递每个元素作为任何命令使用替换的自己的参数。 echo将输出由空格分隔的每个参数:

  
$ echo `echo Line 1; echo Line 2; echo Line 3`
Line 1 Line 2 Line 3

但是,当您引用替换时,不应用单词拆分,因此\n被视为字符串文字:

$ echo "`echo Line 1; echo Line 2; echo Line 3`"
Line 1
Line 2
Line 3

Windows行结尾

与* nix操作系统不同,Windows不使用换行符\n作为换行符。相反,它使用回车符\r和换行符\n的组合,换句话说,\r\n

在POSIX环境中,终端中的\r与打字机非常相似,会将当前位置返回到行的开头。

因此,通常你在Linux上阅读Windows格式的文件时看不到很多问题,因为虽然它有额外的\r个字符,但它仍然包含一个\n。串联使用的两个具有相同的效果:返回到行的前面然后移动到下一行。冗余,但仍然让你到同一个地方。

那为什么会发生这种情况呢?

请记住,我说通常在读取* nix中的文件(或流或其他内容)时,不会导致问题产生\r个字符。但在这里你有一个例子,说明情况并非如此。

以下是您运行ipconfig > temp; echo `cat temp`时所发生的事情的一步一步:

  1. ipconfig.exe会运行并将其输出重定向到文件temp
  2. cat temp运行,其输出由bash解析。
  3. 命令替换是不加引号的,因此bash会将结果拆分为whitepsace。
  4. 拆分结果将传递给echo
  5. echo打印以空格分隔的参数。
  6. 最终,echo打印ipconfig.exe输出的第一行的最后一段文字。但是,该行最后包含\r,因为ipconfig.exe是Windows命令并使用Windows行结尾,因此在打印完该位文本后,终端中的位置将返回到这条线。
  7. echo继续打印参数,但每次打印\r时,后续输出都会覆盖从行开头打印的文本。
  8. 这就是你获得输出的原因。如你所说,你有

    Connection-specific DNS Suffix . : Media disconnected2A612}:%62
    

    因此,我猜测ipconfig.exe输出的最后一行是

    Connection-specific DNS Suffix . : Media disconnected
    

    并且它打印的最长文本行以612}:%62结尾(可能是IPv6地址),第二长文本以2A结尾。