啊!找到了。
确保您不会在命令末尾意外发送换行符 (\n)
看起来echo 在字符串中添加了一个尾随换行符,而printf 没有,并且这个尾随换行符干扰了设备解析命令的能力。如果我强行将它(换行符,\n)添加到 printf cmd 的末尾,那么它也会失败——这意味着设备不会按预期响应命令:
# fails:
printf 'measure:voltage? ch1\n' | timeout 0.2 nc 192.168.0.1 9999
...看起来您可以使用 -n 抑制来自 echo 的尾随换行符:
# works!
echo -n 'measure:voltage? ch1' | timeout 0.2 nc 192.168.0.1 9999
# also works, of course, as stated in the question
printf 'measure:voltage? ch1' | timeout 0.2 nc 192.168.0.1 9999
来自man echo:
-n do not output the trailing newline
关键要点:使用 printf 或 echo -n 在打印的末尾不要有尾随换行符。
但是,这还没有结束!这里还有两点:
1。如果您想要可移植的和预期的行为,以及向设备发送任何命令的能力,请不要在任何 shell 脚本中使用echo!
使用echo 根本 在尝试使用它向设备发送任何可能的字符串时实际上是一个坏主意!为什么?好吧,@Jeff Schaller 向我指出了以下资源in the comments,它有 吨 非常有价值的信息:Unix & Linux: Why is printf better than echo?。
不使用echo 的几个主要原因包括:
-
它的实现、参数和行为都有点hacky。
-
它是不可移植的:它有各种不同的实现方式。有些支持-e 和-n,有些不支持。有些默认情况下具有-e 行为,而没有-e。等等。
-
它不能将-n 打印为命令,在某些 shell 上完全。见my comment here。
在 Ubuntu 18.04 和 20.04 上的 bash 上,echo "-n" 应该输出 -n。相反,它不输出任何内容,因为它接受与 -n 标志相同的内容。 echo -- "-n" 应该解决这个问题并输出-n,但事实并非如此。它改为输出-- -n。我现在非常明白你的观点。 printf 更好。
-
正如@Charles Duffy 指出的in the comments:甚至the POSIX specification for echo 也建议不要使用echo,原因有很多:
不可能在所有 POSIX 系统中可移植地使用 echo...
鼓励新应用程序使用printf 而不是echo。
仅供参考,以下是来自Unix & Linux: Why is printf better than echo? 的几个关键引述:
关于echo:
...确保$var 不包含反斜杠字符且不以- 开头
关于printf:
但请记住第一个参数是格式,因此不应包含可变/不受控制的数据。
2。使用printf正确作为printf '%s' "my command string",而不是printf "my command string"
在下面的 cmets 中查看我和@Charles Duffy 之间的更多讨论。你应该像这样使用printf:
# CORRECT USAGE: >>> FINAL ANSWER; DO THIS! <<<
printf '%s' 'measure:voltage? ch1' | timeout 0.2 nc 192.168.0.1 9999
# NOT this:
printf 'measure:voltage? ch1' | timeout 0.2 nc 192.168.0.1 9999
这是因为传递给printf 的第一个参数被解析为格式字符串。例如,如果您尝试发送到设备的命令字符串是%s,则它不会发送任何内容!:
printf "%s"
输出为空,因为printf 将第一个参数解释为格式字符串,而%s 表示格式字符串中的特殊内容。但这确实将%s 作为文字发送:
printf "%s" "%s"
输出是
%s
printf 的参数中的第一个"%s" 是格式字符串,第二个"s" 是要替换为格式字符串的字符串文字根据printf 规范,第一个%s 所在的位置。
这意味着printf的正确用法将能够向设备发送任何命令,而错误用法将去除任何格式字符,例如%s、%02X、%u等 - 任何printf-style format string special chars or sequences。
另见:
- Unix & Linux: Why is printf better than echo?
- the POSIX specification for
echo