shell - 如何执行参数中带引号的命令?

标签 shell rust command-line-arguments execute

我正在尝试运行命令

rsync -rtv -e 'ssh -i /Users/yuanlinfeng/.ssh/id_rsa -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking no" -o "ConnectTimeout=2"' /tmp/a username@ip:/home/ubuntu/a

代码是:

let login_settings = format!(r#"'ssh -i {} -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking no" -o "ConnectTimeout=2"'"#, identity);
let mut cmd = Command::new("rsync");
cmd.env("SETTING", login_settings);
cmd.arg("-rtv").arg("-e").arg(login_settings);
if delete {
    cmd.arg("--delete");
}
match exclude_files {
    None => {}
    Some(exclude_files) => {
        for file in exclude_files.iter() {
            cmd.arg("--exclude").arg(file);
        }
    }
}
let target = format!("{}@{}:{}", username, remote_ip, dest);
cmd.arg(source).arg(target);
let output = cmd.output()?;
if output.stdout.len() > 0 {
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
}
if output.stderr.len() > 0 {
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
}

错误:

stderr: rsync: Failed to exec ssh -i /Users/yuanlinfeng/.ssh/id_rsa -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking no" -o "ConnectTimeout=2": No such file or directory (2)
rsync error: error in IPC code (code 14) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-52/rsync/pipe.c(86) [sender=2.6.9]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-52/rsync/io.c(453) [sender=2.6.9]

看起来参数中的引号被删除了。我该如何修复它?

我使用的是 macOS High Sierra 和 Rust 1.22.1。

最佳答案

ssh ... 参数周围的 ' 引号实际上并未传递给 rsync; shell 使用它们来分隔 rsync 的参数。

您的 Rust 代码尝试调用如下内容:rsync -e "'ssh ...'"...。 rsync 然后尝试像 shell 一样分割 'ssh ...' 参数(看起来它实际上并没有使用 shell 来扩展它)。这意味着它将把 ssh ... 视为一个参数(要执行的文件名),但这样的文件不存在。

删除 format! 调用中的 ' 引号,它可能会起作用。

在 Linux 上,您可以通过 strace -ff -e trace=execve -- ./target/... 运行示例,看看它是如何工作的。 macOS 有 dtruss,但我无法帮助您:)

关于shell - 如何执行参数中带引号的命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47726187/

相关文章:

linux - 国家和外部 IP Bash 脚本

rust - Rust:如何在功能链中使用await

c++ - 需要有关如何设置 getopt_long 以正确传递命令行参数的建议

c - 如何在 Linux 中将星号作为命令行参数?

python - 直接在 Windows 上运行 python 文件时丢弃的命令行参数

shell - 如何使用linux命令在每个目录中查找和删除特定文件

linux - 如何从 SFTP 服务器获取文件并将它们移动到 bash 脚本中的另一个文件夹?

git - 检查是否需要在 Git 中 pull

rust - 从 u8 切片创建读取特征对象

rust - 如何使用 Cargo 修补 crates-io 的路径?