xzzy 发表于 2023-03-05 18:32
Tags:ssh
想做到类似windows原生ssh命令,现在一点思路也没有。麻烦大佬们指指路!
功能倒是实现出来了,就是 vim直接寄、tab联想代码没思路
如何异步读写
大部分问题解决了:
mode.set_boolean(ssh2::PtyModeOpcode::ECHO, false); //关闭回显 mode.set_boolean(ssh2::PtyModeOpcode::IGNCR, true); //忽略输入的回车
但是输出的时候还是会有一个空行...
根据ssh2的文档和一些例子写了个勉强能跑起来的程序:
#![allow(unused)] use { ssh2::Session, std::{ io::{stdin, stdout, Read, Write}, net::TcpStream, thread, }, }; fn main() -> Result<(), Box<dyn std::error::Error>> { let mut sess = Session::new()?; sess.set_tcp_stream(TcpStream::connect("127.0.0.1:22")?); sess.handshake()?; sess.userauth_password("u0_a36", "123456")?; let mut channel = sess.channel_session()?; channel.request_pty("xterm", None, None)?; channel.shell()?; channel.handle_extended_data(ssh2::ExtendedData::Merge)?; sess.set_blocking(false); let mut ssh_stdin = channel.stream(0); let stdin_thread = thread::spawn(move || { let mut buf = [0; 1024]; loop { let size = stdin().read(&mut buf).unwrap(); ssh_stdin.write_all(&buf[..size]).unwrap(); } }); let stdout_thread = thread::spawn(move || { loop { let mut buf = [0; 1024]; match channel.read(&mut buf) { Ok(c) if c > 0 => { print!("{}", std::str::from_utf8(&buf).unwrap()); stdout().flush().unwrap(); } Ok(0) => break, _ => (), } } channel.close().unwrap(); print!("Exit: {}", channel.exit_status().unwrap()); }); stdin_thread.join().unwrap(); stdout_thread.join().unwrap(); Ok(()) }
但是运行过程中有问题,向流写入命令后输出的字符不正常,总是会包含命令的回声,例如:
~ $ ls ls xxx xxx ~ $ ~ $
望大佬们解解惑!
github.com/alexcrichton/ssh2-rs Rust bindings to libssh2, an ssh client library.
chatGPT不实时,这些都是老的代码,现在不一定能运行
use ssh2::Session; use std::{ io::{Read, Write}, net::TcpStream, }; fn main() { // 连接到 SSH 服务器 let tcp = TcpStream::connect("127.0.0.1:22").unwrap(); let mut sess = Session::new().unwrap(); sess.set_tcp_stream(tcp); sess.handshake().unwrap(); // 身份验证 sess.userauth_password("a", "123456").unwrap(); // 创建交互式会话通道 let mut channel = sess.channel_session().unwrap(); channel.request_pty("xterm", None, None).unwrap(); channel.shell().unwrap(); // 从本地终端读取输入并将其发送到远程终端 let mut input = String::new(); loop { std::io::stdin().read_line(&mut input).unwrap(); channel.write_all(input.as_bytes()).unwrap(); input.clear(); let mut buffer = [0; 1024]; let size = channel.read(&mut buffer).unwrap(); let output = std::str::from_utf8(&buffer[..size]).unwrap(); print!("{}", output); } }
chatGPT的例子,但是有问题,终端的输出不正常
-- 👇 ChenGuoHui: ChatGPT可以给示例代码吗? :)
ChatGPT可以给示例代码吗? :)
ChatGPT回答
如果你想要实现一个类似于Windows原生SSH命令的工具,你可以考虑使用Rust语言来编写。以下是一些实现这个目标的思路和建议: 熟悉SSH协议和其工作原理:在开始编写SSH客户端之前,你需要了解SSH协议和其工作原理。这将有助于你设计和编写代码,并帮助你更好地理解如何使用SSH。 选择SSH库:Rust社区有许多SSH库可供选择,例如russh、ssh2和thrussh等。这些库提供了SSH客户端和服务器的功能,可以帮助你快速地实现SSH客户端。 编写代码:使用选定的SSH库,你可以开始编写代码。你需要定义SSH连接的参数,例如用户名、密码、IP地址、端口等。然后,你可以使用库提供的函数来建立SSH连接,执行命令,上传和下载文件等。 处理错误:处理错误是编写稳健程序的重要部分。你需要确保你的代码能够处理任何可能出现的错误,例如网络连接问题、身份验证失败等。 优化性能:SSH客户端可能需要处理大量数据,因此优化性能也是很重要的。你可以使用Rust提供的并发和异步编程工具来提高程序的效率。 总之,实现类似于Windows原生SSH命令的工具需要你具备一定的Rust编程经验和SSH协议的知识。但是,通过选择合适的SSH库和编写高质量的代码,你可以很快地实现这个目标。
评论区
写评论功能倒是实现出来了,就是 vim直接寄、tab联想代码没思路
如何异步读写
大部分问题解决了:
但是输出的时候还是会有一个空行...
根据ssh2的文档和一些例子写了个勉强能跑起来的程序:
但是运行过程中有问题,向流写入命令后输出的字符不正常,总是会包含命令的回声,例如:
望大佬们解解惑!
github.com/alexcrichton/ssh2-rs Rust bindings to libssh2, an ssh client library.
chatGPT不实时,这些都是老的代码,现在不一定能运行
chatGPT的例子,但是有问题,终端的输出不正常
--
👇
ChenGuoHui: ChatGPT可以给示例代码吗? :)
ChatGPT可以给示例代码吗? :)
ChatGPT回答
如果你想要实现一个类似于Windows原生SSH命令的工具,你可以考虑使用Rust语言来编写。以下是一些实现这个目标的思路和建议: 熟悉SSH协议和其工作原理:在开始编写SSH客户端之前,你需要了解SSH协议和其工作原理。这将有助于你设计和编写代码,并帮助你更好地理解如何使用SSH。 选择SSH库:Rust社区有许多SSH库可供选择,例如russh、ssh2和thrussh等。这些库提供了SSH客户端和服务器的功能,可以帮助你快速地实现SSH客户端。 编写代码:使用选定的SSH库,你可以开始编写代码。你需要定义SSH连接的参数,例如用户名、密码、IP地址、端口等。然后,你可以使用库提供的函数来建立SSH连接,执行命令,上传和下载文件等。 处理错误:处理错误是编写稳健程序的重要部分。你需要确保你的代码能够处理任何可能出现的错误,例如网络连接问题、身份验证失败等。 优化性能:SSH客户端可能需要处理大量数据,因此优化性能也是很重要的。你可以使用Rust提供的并发和异步编程工具来提高程序的效率。 总之,实现类似于Windows原生SSH命令的工具需要你具备一定的Rust编程经验和SSH协议的知识。但是,通过选择合适的SSH库和编写高质量的代码,你可以很快地实现这个目标。