简体   繁体   English

std::process::Command 无法在 macOS 上运行 hdiutil(挂载失败 - 没有此类文件或目录),但该命令在终端中运行时运行良好

[英]std::process::Command cannot run hdiutil on macOS (mount failed - No such file or directory) but the command works fine when run in the terminal

hdiutils , when fed a correct path to a valid file, returns error 2, no such file or directory . hdiutils ,当为有效文件提供正确路径时,返回error 2, no such file or directory When I join the indices of the command array with " " , print them, copy them and run the exact string in a terminal, it works fine.当我用" "加入命令数组的索引时,打印它们,复制它们并在终端中运行确切的字符串,它工作正常。

This is the function edited to contain only the relevant bits.这是编辑为仅包含相关位的功能。 In order to reproduce my error, you will need a disk image located at ~/Downloads/StarUML.dmg .为了重现我的错误,您需要一个位于~/Downloads/StarUML.dmg的磁盘映像。

use std::env;
use std::fs;
use std::process::Command;

fn setup_downloads(download_name: &str) {
    let downloads_path: String = {
        if cfg!(unix) {
            //these both yield options to unwrap
            let path = env::home_dir().unwrap();
            let mut downloads_path = path.to_str().unwrap().to_owned();
            downloads_path += "/Downloads/";
            downloads_path
        } else {
            "we currently only support Mac OS".to_string()
        }
    };

    let files_in_downloads =
        fs::read_dir(&downloads_path).expect("the read_dir that sets files_in_downloads broke");
    let mut file_path: String = "None".to_string();
    for file_name in files_in_downloads {
        let file_name: String = file_name
            .expect("the pre string result which sets file_name has broken")
            .file_name()
            .into_string()
            .expect("the post string result which sets file_name has broken")
            .to_owned();

        if file_name.contains(&download_name) {
            file_path = format!("'{}{}'", &downloads_path, &file_name);
        }
    }

    let len = file_path.len();

    if file_path[len - 4..len - 1] == "dmg".to_string() {
        let mount_command = ["hdiutil", "mount"];
        let output = Command::new(&mount_command[0])
            .arg(&mount_command[1])
            .arg(&file_path)
            .output()
            .expect("failed to execute mount cmd");

        if output.status.success() {
            println!(
                "command successful, returns: {}",
                String::from_utf8_lossy(&output.stderr).into_owned()
            );
        } else {
            println!(
                "command failed, returns: {}",
                String::from_utf8_lossy(&output.stderr).into_owned()
            );
        }
    }
}

fn main() {
    setup_downloads(&"StarUML".to_string());
}

如果在下载中检测到正确的文件时评估为真

来自 process::Command 的错误响应

Split your Command into a variable and print it using the debugging formatter after you have specified the arguments:将您的Command拆分为一个变量,并在指定参数后使用调试格式化程序打印它:

let mut c = Command::new(&mount_command[0]);

c
    .arg(&mount_command[1])
    .arg(&file_path);

    println!("{:?}", c);

This outputs这输出

"hdiutil" "mount" "\'/Users/shep/Downloads/StarUML.dmg\'"

Note that Command automatically provides quoting for each argument, but you have added your own set of single quotes:请注意, Command自动为每个参数提供引号,但您已添加自己的一组单引号:

format!("'{}{}'", &downloads_path, &file_name);
//       ^    ^

Remove these single quotes.删除这些单引号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM