[英]How do I pass a single string with multiple arguments to std::process::Command?
Rust 的std::process::Command
类型要求进程参数通过.arg("-arg1").arg("-arg2")
或作为字符串向量通过.args(&["-arg1", "-arg2"])
。 如何将字符串拆分为可以作为参数传递的向量?
将命令行字符串拆分为参数时,shell 所做的事情绝非易事,尤其是当您想处理诸如引用之类的事情时。 例如,您的代码应通过以下断言:
assert_eq!(split(r#""foo\"bar""#), vec!["foo\"bar"]);
assert_eq!(split(r#""foo"#), vec!["\"foo"]); // Or error
除非您认为简单地在空格上拆分就足以满足您的用例,否则您真的应该使用像shell-words
或shlex
这样的箱子。 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!
}
不支持带引号的参数的实现(但易于添加):
fn sh(command: &str) -> std::io::Result<std::process::Output> {
let mut the_args = command.split(' '); // todo: support quoted strings
let first: &str = the_args.next().unwrap();
let rest: Vec<&str> = the_args.collect::<Vec<&str>>();
std::process::Command::new(first).args(rest).output()
}
fn main() {
let output = sh("ls -la").unwrap();
let s = String::from_utf8_lossy(&output.stdout).to_string();
println!("{:?}", s);
}
你必须用迭代器和字符串转换做很多歌舞。 这让我绊倒了几天。 我希望有人可以用一个基本的解析器来处理引用的参数字符串:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.