String 如何将带有多个参数的单个字符串传递给std::process::Command?

String 如何将带有多个参数的单个字符串传递给std::process::Command?,string,rust,command-line-arguments,child-process,String,Rust,Command Line Arguments,Child Process,Rust的std::process::Command类型要求通过.arg(“-arg1”).arg(“-arg2”)单独传入进程参数,或者通过.args(&[“-arg1”,“-arg2]”)以字符串向量的形式传入进程参数。。如何将字符串拆分为可以作为参数传递的向量?不支持引用参数(但易于添加)的实现: fn-sh(命令:&str)->std::io::Result{ 让mut the_args=command.split(“”);//todo:支持带引号的字符串 让我们先来:&str=_arg

Rust的
std::process::Command
类型要求通过
.arg(“-arg1”).arg(“-arg2”)
单独传入进程参数,或者通过
.args(&[“-arg1”,“-arg2]”)以字符串向量的形式传入进程参数。
。如何将字符串拆分为可以作为参数传递的向量?

不支持引用参数(但易于添加)的实现:

fn-sh(命令:&str)->std::io::Result{
让mut the_args=command.split(“”);//todo:支持带引号的字符串
让我们先来:&str=_args.next().unwrap();
let rest:Vec=the_args.collect::();
std::process::Command::new(first).args(rest).output()
}
fn main(){
让输出=sh(“ls-la”).unwrap();
设s=String::from_utf8_lossy(&output.stdout).to_String();
println!(“{:?}”,s);
}

您必须使用迭代器和字符串转换进行大量的歌舞表演。这件事使我绊倒了几天。我希望有人能加入一个处理引用参数字符串的基本解析器:)。

shell在将命令行字符串拆分为参数时所做的工作绝非小事,尤其是当您想要处理引用之类的事情时。例如,您的代码应该传递以下断言:

assert_eq!(split(r#""foo\"bar""#), vec!["foo\"bar"]);
assert_eq!(split(r#""foo"#), vec!["\"foo"]);          // Or error
除非您认为对于您的用例来说,简单地拆分空白就足够了,否则您真的应该使用类似or的板条箱
shlex
的优点是它可以返回迭代器,从而避免不必要的分配,但另一方面,它很容易在上面的第二个测试中忽略错误:

extern crate shell_words;
extern crate shlex;

use shell_words::split;
use shlex::Shlex;

fn main() {
    assert_eq!(split(r#"a b"#).unwrap(), vec!["a", "b"]);
    let mut lex = Shlex::new(r#"a b"#);
    assert_eq!(lex.by_ref().collect::<Vec<_>>(), vec!["a", "b"]);
    assert!(!lex.had_error);    // ← Don't forget this check!

    assert_eq!(split(r#"a "b c""#).unwrap(), vec!["a", "b c"]);
    let mut lex = Shlex::new(r#"a "b c""#);
    assert_eq!(lex.by_ref().collect::<Vec<_>>(), vec!["a", "b c"]);
    assert!(!lex.had_error);    // ← Don't forget this check!

    assert_eq!(split(r#""foo\"bar""#).unwrap(), vec!["foo\"bar"]);
    let mut lex = Shlex::new(r#""foo\"bar""#);
    assert_eq!(lex.by_ref().collect::<Vec<_>>(), vec!["foo\"bar"]);
    assert!(!lex.had_error);    // ← Don't forget this check!

    assert!(split(r#""foo"#).is_err());
    // assert_eq!(Shlex::new(r#""foo"#).collect::<Vec<_>>(), vec!["\"foo"]);

    let mut lex = Shlex::new(r#""foo"#);
    lex.by_ref().for_each (drop);
    assert!(lex.had_error);     // ← Don't forget this check!
}
extern板条箱外壳\u字;
外部板条箱;
使用shell_单词::split;
使用shlex::shlex;
fn main(){
assert#eq!(split(r#“ab”#)。unwrap(),vec![“a”,“b]);
让mut-lex=Shlex::new(r#“ab”#);
assert_eq!(lex.by_ref().collect::(),vec![“a”,“b]);
断言!(!lex.had_error);//← 别忘了这张支票!
assert#eq!(split(r#“a”bc”“).unwrap(),vec![“a”,“bc”);
让mut-lex=Shlex::new(r#“a”b“c”);
assert_eq!(lex.by_ref()collect:(),vec![“a”,“bc]);
断言!(!lex.had_error);//← 别忘了这张支票!
assert#eq!(split(r#“foo\”bar”“).unwrap(),vec![“foo\”bar]);
让mut-lex=Shlex::new(r#“foo\”bar“#”);
assert_eq!(lex.by_ref().collect::(),vec![“foo\”bar]);
断言!(!lex.had_error);//← 别忘了这张支票!
断言!(split(r#“foo”#)。is_err();
//assert#u eq!(Shlex::new(r#“foo”)。collect:(),vec![“foo”);
让mut-lex=Shlex::new(r#“foo”);
每一个的lex.by_ref()(下降);
断言!(lex.had_错误);//← 别忘了这张支票!
}

或者您可以使用板条箱为您完成此操作…@Jmb shell Word采用字符串向量,而不是字符串。我特别感兴趣的是一种从命令行传入字符串并让它“运行”的快速黑客方法,这样我就可以继续使用它了。下注者能更好地解决我自己的问题吗?@ JMB,考虑发表一个备选答案吗?理想情况下,不需要太多的依赖项,但从拆分函数的角度来看,这是非常重要的。std::env::args()似乎通过sys::args::args()处理特定于平台的参数,但不确定是否可以使用它。以
&str
为例,而不是字符串向量。你至少可以。我真的很喜欢语法突出显示是如何正确转义字符串是多么困难的最好例子。
assert\u eq行看起来不正确
extern crate shell_words;
extern crate shlex;

use shell_words::split;
use shlex::Shlex;

fn main() {
    assert_eq!(split(r#"a b"#).unwrap(), vec!["a", "b"]);
    let mut lex = Shlex::new(r#"a b"#);
    assert_eq!(lex.by_ref().collect::<Vec<_>>(), vec!["a", "b"]);
    assert!(!lex.had_error);    // ← Don't forget this check!

    assert_eq!(split(r#"a "b c""#).unwrap(), vec!["a", "b c"]);
    let mut lex = Shlex::new(r#"a "b c""#);
    assert_eq!(lex.by_ref().collect::<Vec<_>>(), vec!["a", "b c"]);
    assert!(!lex.had_error);    // ← Don't forget this check!

    assert_eq!(split(r#""foo\"bar""#).unwrap(), vec!["foo\"bar"]);
    let mut lex = Shlex::new(r#""foo\"bar""#);
    assert_eq!(lex.by_ref().collect::<Vec<_>>(), vec!["foo\"bar"]);
    assert!(!lex.had_error);    // ← Don't forget this check!

    assert!(split(r#""foo"#).is_err());
    // assert_eq!(Shlex::new(r#""foo"#).collect::<Vec<_>>(), vec!["\"foo"]);

    let mut lex = Shlex::new(r#""foo"#);
    lex.by_ref().for_each (drop);
    assert!(lex.had_error);     // ← Don't forget this check!
}