| 2704 | |
| 2705 | #[allow(clippy::too_many_lines)] |
| 2706 | fn execute_shell_command( |
| 2707 | shell: &str, |
| 2708 | command: &str, |
| 2709 | timeout: Option<u64>, |
| 2710 | run_in_background: Option<bool>, |
| 2711 | ) -> std::io::Result<runtime::BashCommandOutput> { |
| 2712 | if run_in_background.unwrap_or(false) { |
| 2713 | let child = std::process::Command::new(shell) |
| 2714 | .arg("-NoProfile") |
| 2715 | .arg("-NonInteractive") |
| 2716 | .arg("-Command") |
| 2717 | .arg(command) |
| 2718 | .stdin(std::process::Stdio::null()) |
| 2719 | .stdout(std::process::Stdio::null()) |
| 2720 | .stderr(std::process::Stdio::null()) |
| 2721 | .spawn()?; |
| 2722 | return Ok(runtime::BashCommandOutput { |
| 2723 | stdout: String::new(), |
| 2724 | stderr: String::new(), |
| 2725 | raw_output_path: None, |
| 2726 | interrupted: false, |
| 2727 | is_image: None, |
| 2728 | background_task_id: Some(child.id().to_string()), |
| 2729 | backgrounded_by_user: Some(true), |
| 2730 | assistant_auto_backgrounded: Some(false), |
| 2731 | dangerously_disable_sandbox: None, |
| 2732 | return_code_interpretation: None, |
| 2733 | no_output_expected: Some(true), |
| 2734 | structured_content: None, |
| 2735 | persisted_output_path: None, |
| 2736 | persisted_output_size: None, |
| 2737 | sandbox_status: None, |
| 2738 | }); |
| 2739 | } |
| 2740 | |
| 2741 | let mut process = std::process::Command::new(shell); |
| 2742 | process |
| 2743 | .arg("-NoProfile") |
| 2744 | .arg("-NonInteractive") |
| 2745 | .arg("-Command") |
| 2746 | .arg(command); |
| 2747 | process |
| 2748 | .stdout(std::process::Stdio::piped()) |
| 2749 | .stderr(std::process::Stdio::piped()); |
| 2750 | |
| 2751 | if let Some(timeout_ms) = timeout { |
| 2752 | let mut child = process.spawn()?; |
| 2753 | let started = Instant::now(); |
| 2754 | loop { |
| 2755 | if let Some(status) = child.try_wait()? { |
| 2756 | let output = child.wait_with_output()?; |
| 2757 | return Ok(runtime::BashCommandOutput { |
| 2758 | stdout: String::from_utf8_lossy(&output.stdout).into_owned(), |
| 2759 | stderr: String::from_utf8_lossy(&output.stderr).into_owned(), |
| 2760 | raw_output_path: None, |
| 2761 | interrupted: false, |
| 2762 | is_image: None, |
| 2763 | background_task_id: None, |