如何在 Rust 中正确地将 dd 命令传输到 netcat 命令?
我对 Rust 相当陌生,正在尝试将 dd 命令通过管道传递给 netcat 命令来检查两台机器之间的网络带宽。
总命令为: dd if=/dev/zero bs=16000 count=625 | nc -v <我的 IP> <端口号>。
到目前为止我的代码:
use std::process::Command;
use std::process::Stdio;
use std::io::Write;
use std::io::Read;
use std::fs::File;
fn main()
{
let mut dd_cmd = Command::new("dd")
.args(&["if=/dev/zero", "bs=16000",
"count=625"])
.output()
.unwrap();
let mut nc_cmd = Command::new("nc")
.args(&["-v", "<my IP>", "<port Number>"])
.stdin(Stdio::piped())
.spawn()
.unwrap();
nc_cmd.stdin.unwrap().write_all(&dd_cmd.stdout).unwrap();
}
(注意:我知道我没有进行错误检查,并且我的 IP 地址和端口号的 nc 命令参数已更改。这样做是出于安全原因。)
我希望输出如下:
问题:
我可以成功地将文件传输到另一台计算机,并且文本显示在终端中。但是,在第一台机器上我没有收到任何有关网络带宽的信息。我在第一台机器的终端中看到的只是“...反向主机查找失败...”和“(未知)...”行。但是,如果我只是测试 dd 命令并将第 11 行从“.output()”更改为“.spawn()”,那么我就可以在第一台机器的终端中看到网络带宽信息。经过在线研究后,我了解到spawn()默认情况下会使stdin和stdout从父进程继承,而output()默认情况下会使stdin和stdout通过管道传输()。我不明白为什么我能够成功传输数据但丢失了实际的带宽信息。该信息不是 dd 命令输出的一部分吗?它不应该出现在传输数据的任何地方吗?
一个奇怪的结果:
我可以打开一个文件并将其写入 nc 命令的标准输入。当我这样做时,我实际上可以在第一台机器的终端中看到带宽信息!
I am fairly new to Rust and am trying to pipe a dd command to a netcat command to check the network bandwidth between two machines.
The total command is: dd if=/dev/zero bs=16000 count=625 | nc -v <my IP> <port number>.
My code so far:
use std::process::Command;
use std::process::Stdio;
use std::io::Write;
use std::io::Read;
use std::fs::File;
fn main()
{
let mut dd_cmd = Command::new("dd")
.args(&["if=/dev/zero", "bs=16000",
"count=625"])
.output()
.unwrap();
let mut nc_cmd = Command::new("nc")
.args(&["-v", "<my IP>", "<port Number>"])
.stdin(Stdio::piped())
.spawn()
.unwrap();
nc_cmd.stdin.unwrap().write_all(&dd_cmd.stdout).unwrap();
}
(Note: I am aware that I am not error checking and that my nc command arguments for IP address and port number are changed. This is done for security reasons.)
What I want the output to look like:
The Problem:
I can successfully transfer files to the other machine and the text shows up in the terminal. However, on the first machine I don't receive any information about the network bandwidth. All I see in the terminal of the first machine are the "...inverse host lookup failed..." and "(UNKNOWN)..." lines. But, if I just test the dd command and change line 11 from ".output()" to ".spawn()", then I am able to see the network bandwidth information in the terminal of the first machine. After researching online, I understand that spawn() will by default make the stdin and stdout inherit from the parent process and output() will by default make the stdin and stdout be piped(). I don't understand why I am able to successfully transfer the data but lose the actual bandwidth information. Is that information not a part of the dd command output? Shouldn't it show up wherever the transferred data does as well?
A weird result:
I can open up a file and write it to the stdin of the nc command. When I do it this way, I can actually see the bandwidth information in the terminal of the first machine!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否希望将使用
dd
传输的数据与dd
的统计报告混合在一起?这听起来像是会破坏你正在传输的任何东西。或者至少 dd 的设计者是这么认为的,这就是为什么 dd 将其传输的数据发送到 stdout,而将自己的数据发送到 stderr。因此,如果您想将两者都发送到管道中的下一个阶段,则需要将两者都发送。
或者您的意思是,当您运行此命令时,来自 dd 的信息不会显示在您的终端中?那是因为
因此,
stderr
被捕获,存储在缓冲区中,然后在程序终止时掉落在地上。顺便说一句,您的 dd 在这里似乎不太有用:output 将启动子进程,等到它终止,并将其所有输出收集在 Vec< 中;u8>。所以这是一个非常复杂且低效的版本:
Would you want the data you're transferring with
dd
anddd
's stats reporting to be intermixed? That sounds like something which would break whatever you're transferring.Or at least
dd
's designers thought so, which is whydd
sends the data it transfers to stdout, but sends its own data to stderr. So if you want to send both over to the next stage in your pipeline, you need to send both.Or maybe you mean that when you run this the information from
dd
does not show up in your terminal? That would be becauseSo
stderr
is captured, stored in a buffer, then dropped on the ground when the program terminates.Incidentally your
dd
does not seem very useful here:output
is going to start the child process, wait until it terminates, and collect all of its output in aVec<u8>
. So it's a very complicated and inefficient version of: