Rust执行带SSH参数的rsync终端命令失败,寻求排查解决
解决Rust中执行rsync命令时的"Missing trailing-' in remote-shell command"错误
我帮你分析下问题所在,其实核心是**-e参数的传递方式不符合Rust Command的工作逻辑**:
错误原因
在shell里执行rsync时,我们用单引号把ssh -i ~/path/to/mypem.pem包起来,是为了告诉shell把整段内容当作一个完整参数传给rsync的-e选项。但Rust的Command是直接调用程序、不经过shell解析的——你现在把'ssh、-i、~/path/to/mypem.pem'拆成了三个独立参数,rsync会把第一个参数'ssh'当成远程shell命令,里面的单引号没有闭合,自然就抛出了"Missing trailing-' in remote-shell command"的语法错误。
修正后的代码
把整个ssh命令作为一个完整字符串传给-e,同时去掉多余的单引号:
use std::process::Command; fn main() { let output = Command::new("rsync") .args(&[ "-avL", "--progress", "-e", "ssh -i ~/path/to/mypem.pem", // 这里是完整的单个参数 "../directory/src/file.js", "user@computer:~/data/school" ]) .output() .expect("Failed to execute rsync command"); if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); eprintln!("rsync failed and stderr was:\n{}", s); } println!("{}", String::from_utf8_lossy(&output.stdout)); }
额外注意事项
还有个容易踩的小坑:~/是shell的语法,Rust的Command不会自动把波浪号展开成用户主目录。如果要让程序更健壮,建议用std::env::home_dir()构建绝对路径:
use std::env; use std::path::PathBuf; fn main() { // 构建pem文件的绝对路径 let mut pem_path = env::home_dir().expect("Failed to get user home directory"); pem_path.push("path/to/mypem.pem"); let pem_str = pem_path.to_str().expect("Invalid path string"); let output = Command::new("rsync") .args(&[ "-avL", "--progress", "-e", &format!("ssh -i {}", pem_str), // 用绝对路径替代~ "../directory/src/file.js", "user@computer:~/data/school" ]) .output() .expect("Failed to execute rsync command"); // 后续的错误处理和输出逻辑不变 if !output.status.success() { let s = String::from_utf8_lossy(&output.stderr); eprintln!("rsync failed and stderr was:\n{}", s); } println!("{}", String::from_utf8_lossy(&output.stdout)); }
这样能避免不同shell环境下路径解析不一致的问题。
内容的提问来源于stack exchange,提问作者dwib
相关产品推荐
相关产品推荐

