在Rust中重定向stdio(管道和文件描述符)
我的主要目标是在Rust中实现一个程序,将stdio重定向到本地管道上,类似于此在Rust中重定向stdio(管道和文件描述符),rust,pipe,file-descriptor,stdio,Rust,Pipe,File Descriptor,Stdio,我的主要目标是在Rust中实现一个程序,将stdio重定向到本地管道上,类似于此 程序执行命令“sh”,并在父进程和子进程之间创建管道 子进程的输出通过管道(在本例中是提示符)到达父进程 我在终端上键入一些东西,比如“pwd”,然后这些东西进入到子进程的管道中 子进程执行该命令,并通过管道将输出发送回父进程,并在我的终端上显示当前工作目录 最终,我的目标是让父进程充当代理,并通过远程ncat实例和子进程之间的TLS连接转发此I/O。目前,我正在努力使管道部分正确 我该怎么做?我当前的代码段如
- 程序执行命令“sh”,并在父进程和子进程之间创建管道
- 子进程的输出通过管道(在本例中是提示符)到达父进程
- 我在终端上键入一些东西,比如“pwd”,然后这些东西进入到子进程的管道中
- 子进程执行该命令,并通过管道将输出发送回父进程,并在我的终端上显示当前工作目录
let message_string=string::from(“fd_pipe\0”);
让message=message_string.as_ptr()as*const c_void;
让mut command_output=std::process::command::new(“/bin/sh”)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect(“无法执行命令”);
让command_stdin=command_output.stdin.unwrap();
普林顿!(“command_stdin{}”,command_stdin.as_raw_fd());
让command_stdout=command_output.stdout.unwrap();
普林顿!(“command_stdout{}”,command_stdout.as_raw_fd());
让command_stderr=command_output.stderr.unwrap();
普林顿!(“command_stderr{}”,command_stderr.as_raw_fd());
nix::unistd::dup2(tokio::io::stdin().as_raw_fd(),command_stdin.as_raw_fd());
nix::unistd::dup2(tokio::io::stdout().as_raw_fd(),command_stdout.as_raw_fd());
nix::unistd::dup2(tokio::io::stderr().as_raw_fd(),command_stderr.as_raw_fd());
2020年11月2日编辑
Rust论坛中有人为我提供了一个解决方案(),我想我也会在这里分享
let mut command_output = std::process::Command::new("/bin/sh")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("cannot execute command");
let mut command_stdin = command_output.stdin.unwrap();
println!("command_stdin {}", command_stdin.as_raw_fd());
let copy_stdin_thread = std::thread::spawn(move || {
io::copy(&mut io::stdin(), &mut command_stdin)
});
let mut command_stdout = command_output.stdout.unwrap();
println!("command_stdout {}", command_stdout.as_raw_fd());
let copy_stdout_thread = std::thread::spawn(move || {
io::copy(&mut command_stdout, &mut io::stdout())
});
let command_stderr = command_output.stderr.unwrap();
println!("command_stderr {}", command_stderr.as_raw_fd());
let copy_stderr_thread = std::thread::spawn(move || {
io::copy(&mut command_stderr, &mut io::stderr())
});
copy_stdin_thread.join().unwrap()?;
copy_stdout_thread.join().unwrap()?;
copy_stderr_thread.join().unwrap()?;
我的下一个问题是如何通过TLS连接将重定向的stdio链接到远程ncat侦听器?您不需要复制任何内容,我认为您所缺少的只是
命令\u输出。wait()
。你能澄清什么不起作用吗?另外,.spawn()
意味着Stdio::piped()
因此这些都是不需要的,命令::new(“sh”).spawn().unwrap().wait().unwrap()
应该可以代理shell。您好@kmdreko,谢谢您的建议。我还发布了一个其他人也友好地与我分享的解决方案。