我正在 Linux Ubuntu 18.04 和 20.04 上使用( ) 通过 TCP 以太网向Teledyne LeCroy T3PS3000电源设备发送命令。如果我使用该设备无法正确接收命令,但如果我使用它则工作正常。为什么?netcat
nc
echo
printf
# Example command to Ethernet-connected digital power supply over TCP
# fails
echo 'measure:voltage? ch1' | timeout 0.2 nc 192.168.0.1 5025
# works
printf 'measure:voltage? ch1' | timeout 0.2 nc 192.168.0.1 5025
Run Code Online (Sandbox Code Playgroud)
timeout
cmd: https: //unix.stackexchange.com/questions/492766/usage-of-nc-with-timeouts-in-ms/492796#492796
printf
下面的表格是正确的):如果没有该timeout
命令,我们将不得不使用-w
带有 的选项netcat
,但它只接受以秒为单位的整个整数等待周期超时,如下所示(-w 1
注意将“等待”时间或超时设置为 1 整秒):
printf '%s' "my command to send" | nc -w1 192.168.0.1 5025
Run Code Online (Sandbox Code Playgroud)
- 如需帮助,请联系:
Teledyne LeCroy 支持
support@teledynelecroy.com
700 Chestnut Ridge Road
Chestnut Ridge, NY 10977
(800) 553-2769 选项 3- 手册中没有,所以我给他们发了电子邮件,他们告诉我:
T3PS3000采用socket通信方式,默认端口为5025。
- 手册(快速入门指南):http://cdn.teledynelecroy.com/files/manuals/t3ps3000-quick-start-guide.pdf
- p24,“第 3 章远程控制”是命令界面开始的地方。
啊! 找到了。
\n
确保您不会意外在命令末尾发送换行符 ( )它看起来像是echo
在字符串中添加了一个尾随换行符,但printf
事实并非如此,并且这个尾随换行符会干扰设备解析命令的能力。如果我强行将它(换行符,\n
)添加到 cmd 的末尾printf
,那么它也会失败 - 这意味着设备不会按预期响应命令:
# fails:
printf 'measure:voltage? ch1\n' | timeout 0.2 nc 192.168.0.1 9999
Run Code Online (Sandbox Code Playgroud)
...看起来您可以echo
通过使用以下命令来抑制尾随换行符-n
:
# 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
Run Code Online (Sandbox Code Playgroud)
从man echo
:
Run Code Online (Sandbox Code Playgroud)-n do not output the trailing newline
要点:在打印的末尾使用printf
或echo -n
不使用尾随换行符。
但是,这还没有结束!这里还有两点:
echo
使用!当尝试使用它向设备发送任何可能的字符串时,使用echo
at确实是一个坏主意!为什么?好吧,@Jeff Schaller在评论中向我指出了以下资源,其中包含大量真正有价值的信息:Unix & Linux:为什么 printf 比 echo 更好?。
不使用的一些关键原因echo
包括:
它的实现、参数和行为都有点hacky。
它不可移植:它有多种实现方式,在不同的系统中差异很大。有些支持-e
,-n
有些不支持。有些-e
行为默认情况下没有-e
. ETC。
在某些 shell 上,它根本-n
无法作为命令打印。请参阅我的评论。
在 Ubuntu 18.04 和 20.04 上的 bash 上,
echo "-n"
应该输出-n
. 相反,它不输出任何内容,因为它接受与标志相同的东西-n
。echo -- "-n"
应该解决这个问题并输出-n
,但事实并非如此。它-- -n
反而输出。我现在非常明白你的观点了。printf
更好。
正如@Charles Duffy在评论中指出的那样:由于许多不一致和原因,即使是POSIX 规范也echo
建议不要使用:echo
不可能
echo
在所有 POSIX 系统上移植使用...鼓励新应用程序使用
printf
而不是echo
.
仅供参考,这里有一些来自Unix 和 Linux 的关键引言: 为什么 printf 比 echo 更好?:
关于echo
:
...确保
$var
不包含反斜杠字符并且不以-
关于printf
:
但请记住第一个参数是格式,因此不应包含可变/不受控制的数据。
printf
正确使用as printf '%s' "my command string"
, NOTprintf "my command string"
请参阅下面的评论中我和@Charles Duffy 之间的更多讨论。你应该printf
这样使用:
-n do not output the trailing newline
Run Code Online (Sandbox Code Playgroud)
这是因为传递给的第一个参数printf
被解析为格式字符串。例如,如果您尝试发送到设备的命令字符串是%s
,则不会发送任何内容!:
# 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
Run Code Online (Sandbox Code Playgroud)
输出为空,因为printf
将第一个参数解释为格式字符串,并且%s
表示格式字符串中的特殊内容。但这确实%s
以文字形式发送:
printf "%s"
Run Code Online (Sandbox Code Playgroud)
输出是
Run Code Online (Sandbox Code Playgroud)%s
根据规范,"%s"
参数中的第一个printf
是格式字符串,第二个"s"
是要替换为第一个所在格式字符串的字符串文字。%s
printf
这意味着正确的使用printf
将能够向设备发送任何命令,而错误的使用将删除任何格式字符,例如%s
、%02X
、%u
等 - 任何printf
-style 格式字符串特殊字符或序列。
echo
nc
)使用说明,包括设置接收时绑定的IP地址,或发送时发送到的IP地址