forked from extern/nushell
Try to make argument with quotes for external command better (#6420)
* fix arg quote for external * adjust comment
This commit is contained in:
parent
9850424251
commit
fbae137442
@ -501,7 +501,7 @@ impl ExternalCommand {
|
|||||||
|
|
||||||
/// Spawn a command without shelling out to an external shell
|
/// Spawn a command without shelling out to an external shell
|
||||||
pub fn spawn_simple_command(&self, cwd: &str) -> Result<std::process::Command, ShellError> {
|
pub fn spawn_simple_command(&self, cwd: &str) -> Result<std::process::Command, ShellError> {
|
||||||
let (head, _) = trim_enclosing_quotes(&self.name.item);
|
let (head, _, _) = trim_enclosing_quotes(&self.name.item);
|
||||||
let head = nu_path::expand_to_real_path(head)
|
let head = nu_path::expand_to_real_path(head)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string();
|
.to_string();
|
||||||
@ -509,9 +509,15 @@ impl ExternalCommand {
|
|||||||
let mut process = std::process::Command::new(&head);
|
let mut process = std::process::Command::new(&head);
|
||||||
|
|
||||||
for arg in self.args.iter() {
|
for arg in self.args.iter() {
|
||||||
let (trimmed_args, run_glob_expansion) = trim_enclosing_quotes(&arg.item);
|
// if arg is quoted, like "aa", 'aa', `aa`.
|
||||||
|
// `as_a_whole` will be true, so nu won't remove the inner quotes.
|
||||||
|
let (trimmed_args, run_glob_expansion, as_a_whole) = trim_enclosing_quotes(&arg.item);
|
||||||
let mut arg = Spanned {
|
let mut arg = Spanned {
|
||||||
item: remove_quotes(trimmed_args),
|
item: if as_a_whole {
|
||||||
|
trimmed_args
|
||||||
|
} else {
|
||||||
|
remove_quotes(trimmed_args)
|
||||||
|
},
|
||||||
span: arg.span,
|
span: arg.span,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -634,14 +640,18 @@ fn shell_arg_escape(arg: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trim_enclosing_quotes(input: &str) -> (String, bool) {
|
/// This function returns a tuple with 3 items:
|
||||||
|
/// 1st item: trimmed string.
|
||||||
|
/// 2nd item: a boolean value indicate if it's ok to run glob expansion.
|
||||||
|
/// 3rd item: a boolean value indicate if we need to make input as a whole.
|
||||||
|
fn trim_enclosing_quotes(input: &str) -> (String, bool, bool) {
|
||||||
let mut chars = input.chars();
|
let mut chars = input.chars();
|
||||||
|
|
||||||
match (chars.next(), chars.next_back()) {
|
match (chars.next(), chars.next_back()) {
|
||||||
(Some('"'), Some('"')) => (chars.collect(), false),
|
(Some('"'), Some('"')) => (chars.collect(), false, true),
|
||||||
(Some('\''), Some('\'')) => (chars.collect(), false),
|
(Some('\''), Some('\'')) => (chars.collect(), false, true),
|
||||||
(Some('`'), Some('`')) => (chars.collect(), true),
|
(Some('`'), Some('`')) => (chars.collect(), true, true),
|
||||||
_ => (input.to_string(), true),
|
_ => (input.to_string(), true, false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,36 @@ fn failed_command_with_semicolon_will_not_execute_following_cmds() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[test]
|
||||||
|
fn external_args_with_quoted() {
|
||||||
|
Playground::setup("external failed command with semicolon", |dirs, _| {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), pipeline(
|
||||||
|
r#"
|
||||||
|
^echo "foo=bar 'hi'"
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "foo=bar 'hi'");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[test]
|
||||||
|
fn external_arg_with_long_flag_value_quoted() {
|
||||||
|
Playground::setup("external failed command with semicolon", |dirs, _| {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), pipeline(
|
||||||
|
r#"
|
||||||
|
^echo --foo='bar'
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "--foo=bar");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[test]
|
#[test]
|
||||||
fn explicit_glob_windows() {
|
fn explicit_glob_windows() {
|
||||||
|
Loading…
Reference in New Issue
Block a user