反勾弄乱了命令的输出
back ticks messing with output of command
例如:
ipconfig > temp
cat temp
产生正确的结果(ipconfig
的所有输出)。
但是:
ipconfig > temp
echo `cat temp`
产生非常错误的结果:
Connection-specific DNS Suffix . :: Media disconnected2A612}:%62
就是这样,不再打印任何内容,这显然是错误的,因为如果我在编辑器中打开 temp
,我可以清楚地看到正确的输出。
要使其正常工作,请将 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 行结尾
Windows 与 *nix OS 不同,它不使用换行符 \n
作为换行符。相反,它使用回车 return 字符 \r
和换行符 \n
的组合,换句话说,\r\n
.
在 POSIX 环境中,\r
在终端中,就像在打字机上一样,returns 当前位置到行首。
因此,通常 在 Linux 上读取 Windows 格式的文件不会有太大问题,因为虽然它有额外的\r
个字符,它仍然包含一个 \n
。两者串联使用效果相同:return到行首,然后移动到下一行。冗余,但仍会将您带到同一个地方。
那为什么会这样呢?
记住我说过 通常 在读取文件(或流,或其他东西)时 \r
不会导致问题 *尼克斯。但这里有一个情况并非如此的例子。
这是当您 运行 ipconfig > temp; echo `cat temp`
:
时发生的事情的分步说明
ipconfig.exe
运行s 并且它的输出被重定向到文件 temp
.
cat temp
运行s 其输出由 bash
. 解析
- 命令替换未加引号,因此
bash
按 whitepsace 拆分结果。
- 拆分结果传给
echo
.
echo
打印由空格分隔的参数。
- 最终,
echo
在第一行打印了由 ipconfig.exe
输出的最后一段文本。但是,该行末尾包含一个 \r
,因为 ipconfig.exe
是一个 Windows 命令并使用 Windows 行结尾,因此在打印该文本位之后,位置在终端 returns 到行首。
echo
继续打印参数,但每次打印 \r
时,后续输出会覆盖已从行首打印的文本。
这正是您获得输出结果的原因。正如你所说,你得到了
Connection-specific DNS Suffix . : Media disconnected2A612}:%62
因此,我猜测输出的最后一行 ipconfig.exe 是
Connection-specific DNS Suffix . : Media disconnected
并且它打印的最长文本行以 612}:%62
结尾(可能是 IPv6 地址),第二长的文本以 2A
.
结尾
例如:
ipconfig > temp
cat temp
产生正确的结果(ipconfig
的所有输出)。
但是:
ipconfig > temp
echo `cat temp`
产生非常错误的结果:
Connection-specific DNS Suffix . :: Media disconnected2A612}:%62
就是这样,不再打印任何内容,这显然是错误的,因为如果我在编辑器中打开 temp
,我可以清楚地看到正确的输出。
要使其正常工作,请将 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 行结尾
Windows 与 *nix OS 不同,它不使用换行符 \n
作为换行符。相反,它使用回车 return 字符 \r
和换行符 \n
的组合,换句话说,\r\n
.
在 POSIX 环境中,\r
在终端中,就像在打字机上一样,returns 当前位置到行首。
因此,通常 在 Linux 上读取 Windows 格式的文件不会有太大问题,因为虽然它有额外的\r
个字符,它仍然包含一个 \n
。两者串联使用效果相同:return到行首,然后移动到下一行。冗余,但仍会将您带到同一个地方。
那为什么会这样呢?
记住我说过 通常 在读取文件(或流,或其他东西)时 \r
不会导致问题 *尼克斯。但这里有一个情况并非如此的例子。
这是当您 运行 ipconfig > temp; echo `cat temp`
:
ipconfig.exe
运行s 并且它的输出被重定向到文件temp
.cat temp
运行s 其输出由bash
. 解析
- 命令替换未加引号,因此
bash
按 whitepsace 拆分结果。 - 拆分结果传给
echo
. echo
打印由空格分隔的参数。- 最终,
echo
在第一行打印了由ipconfig.exe
输出的最后一段文本。但是,该行末尾包含一个\r
,因为ipconfig.exe
是一个 Windows 命令并使用 Windows 行结尾,因此在打印该文本位之后,位置在终端 returns 到行首。 echo
继续打印参数,但每次打印\r
时,后续输出会覆盖已从行首打印的文本。
这正是您获得输出结果的原因。正如你所说,你得到了
Connection-specific DNS Suffix . : Media disconnected2A612}:%62
因此,我猜测输出的最后一行 ipconfig.exe 是
Connection-specific DNS Suffix . : Media disconnected
并且它打印的最长文本行以 612}:%62
结尾(可能是 IPv6 地址),第二长的文本以 2A
.