start_command/
isolation_shell.rs1const SHELL_NAMES: [&str; 8] = ["bash", "zsh", "sh", "fish", "ksh", "csh", "tcsh", "dash"];
4
5pub fn is_interactive_shell_command(command: &str) -> bool {
6 let parts: Vec<&str> = command.split_whitespace().collect();
7 if parts.is_empty() {
8 return false;
9 }
10 let basename = parts[0].rsplit('/').next().unwrap_or(parts[0]);
11 SHELL_NAMES.contains(&basename) && !parts.contains(&"-c")
12}
13
14pub fn is_shell_invocation_with_args(command: &str) -> bool {
15 let parts: Vec<&str> = command.split_whitespace().collect();
16 if parts.is_empty() {
17 return false;
18 }
19 let basename = parts[0].rsplit('/').next().unwrap_or(parts[0]);
20 SHELL_NAMES.contains(&basename) && parts.contains(&"-c")
21}
22
23pub fn build_shell_with_args_cmd_args(command: &str) -> Vec<String> {
24 let parts: Vec<&str> = command.split_whitespace().collect();
25 let Some(index) = parts.iter().position(|&part| part == "-c") else {
26 return parts.iter().map(|part| (*part).to_string()).collect();
27 };
28 let script = parts[index + 1..].join(" ");
29 let mut result = parts[..=index]
30 .iter()
31 .map(|part| (*part).to_string())
32 .collect::<Vec<_>>();
33 if !script.is_empty() {
34 result.push(script);
35 }
36 result
37}