Nymbo commited on
Commit
78589bf
·
verified ·
1 Parent(s): 1d14ba5

Delete Modules/Shell_Exec.py

Browse files
Files changed (1) hide show
  1. Modules/Shell_Exec.py +0 -139
Modules/Shell_Exec.py DELETED
@@ -1,139 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import platform
5
- import shlex
6
- import subprocess
7
- from typing import Annotated
8
-
9
- import gradio as gr
10
-
11
- from app import _log_call_end, _log_call_start, _truncate_for_log
12
- from ._docstrings import autodoc
13
- from .File_System import _resolve_path, ROOT_DIR, _display_path
14
- import shutil
15
-
16
-
17
- def _detect_shell(prefer_powershell: bool = True) -> tuple[list[str], str]:
18
- """
19
- Pick an appropriate shell for the host OS.
20
- - Windows: use PowerShell by default, fall back to cmd.exe.
21
- - POSIX: use /bin/bash if available, else /bin/sh.
22
- Returns (shell_cmd_prefix, shell_name) where shell_cmd_prefix is the command list to launch the shell.
23
- """
24
- system = platform.system().lower()
25
- if system == "windows":
26
- if prefer_powershell:
27
- pwsh = shutil.which("pwsh")
28
- candidates = [pwsh, shutil.which("powershell"), shutil.which("powershell.exe")]
29
- for cand in candidates:
30
- if cand:
31
- return [cand, "-NoLogo", "-NoProfile", "-Command"], "powershell"
32
- # Fallback to cmd
33
- comspec = os.environ.get("ComSpec", r"C:\\Windows\\System32\\cmd.exe")
34
- return [comspec, "/C"], "cmd"
35
- # POSIX
36
- bash = shutil.which("bash")
37
- if bash:
38
- return [bash, "-lc"], "bash"
39
- sh = os.environ.get("SHELL", "/bin/sh")
40
- return [sh, "-lc"], "sh"
41
-
42
-
43
- # Detect shell at import time for docs/UI purposes
44
- _DETECTED_SHELL_PREFIX, _DETECTED_SHELL_NAME = _detect_shell()
45
-
46
-
47
- # Clarify path semantics and expose detected shell in summary
48
- TOOL_SUMMARY = (
49
- "Execute a shell command within a safe working directory under the tool root ('/'). "
50
- "Paths must be relative to '/'. "
51
- "Set workdir to '.' to use the root. "
52
- "Absolute paths are disabled."
53
- f"Detected shell: {_DETECTED_SHELL_NAME}."
54
- )
55
-
56
-
57
- def _run_command(command: str, cwd: str, timeout: int) -> tuple[str, str, int]:
58
- shell_prefix, shell_name = _detect_shell()
59
- full_cmd = shell_prefix + [command]
60
- try:
61
- proc = subprocess.run(
62
- full_cmd,
63
- cwd=cwd,
64
- stdout=subprocess.PIPE,
65
- stderr=subprocess.PIPE,
66
- text=True,
67
- encoding="utf-8",
68
- errors="replace",
69
- timeout=timeout if timeout and timeout > 0 else None,
70
- )
71
- return proc.stdout, proc.stderr, proc.returncode
72
- except subprocess.TimeoutExpired as exc:
73
- return exc.stdout or "", (exc.stderr or "") + "\n[timeout]", 124
74
- except Exception as exc:
75
- return "", f"Execution failed: {exc}", 1
76
-
77
-
78
- @autodoc(summary=TOOL_SUMMARY)
79
- def Shell_Exec(
80
- command: Annotated[str, "Shell command to execute. Accepts multi-part pipelines as a single string."],
81
- workdir: Annotated[str, "Working directory (relative to root unless UNSAFE_ALLOW_ABS_PATHS=1)."] = ".",
82
- timeout: Annotated[int, "Timeout in seconds (0 = no timeout, be careful on public hosting)."] = 60,
83
- ) -> str:
84
- _log_call_start("Shell_Exec", command=command, workdir=workdir, timeout=timeout)
85
- if not command or not command.strip():
86
- result = "No command provided."
87
- _log_call_end("Shell_Exec", _truncate_for_log(result))
88
- return result
89
-
90
- abs_cwd, err = _resolve_path(workdir)
91
- if err:
92
- _log_call_end("Shell_Exec", _truncate_for_log(err))
93
- return err
94
- if not os.path.exists(abs_cwd):
95
- result = f"Working directory not found: {abs_cwd}"
96
- _log_call_end("Shell_Exec", _truncate_for_log(result))
97
- return result
98
-
99
- # Capture shell used for transparency
100
- _, shell_name = _detect_shell()
101
- stdout, stderr, code = _run_command(command, cwd=abs_cwd, timeout=timeout)
102
- display_cwd = _display_path(abs_cwd)
103
- header = (
104
- f"Command: {command}\n"
105
- f"CWD: {display_cwd}\n"
106
- f"Root: /\n"
107
- f"Shell: {shell_name}\n"
108
- f"Exit code: {code}\n"
109
- f"--- STDOUT ---\n"
110
- )
111
- output = header + (stdout or "<empty>") + "\n--- STDERR ---\n" + (stderr or "<empty>")
112
- _log_call_end("Shell_Exec", _truncate_for_log(f"exit={code} stdout={len(stdout)} stderr={len(stderr)}"))
113
- return output
114
-
115
-
116
- def build_interface() -> gr.Interface:
117
- return gr.Interface(
118
- fn=Shell_Exec,
119
- inputs=[
120
- gr.Textbox(label="Command", placeholder="echo hello || dir", lines=2),
121
- gr.Textbox(label="Workdir", value=".", max_lines=1),
122
- gr.Slider(minimum=0, maximum=600, step=5, value=60, label="Timeout (seconds)"),
123
- ],
124
- outputs=gr.Textbox(label="Output", lines=20),
125
- title="Shell Exec",
126
- description=(
127
- "<div style=\"text-align:center; overflow:hidden;\">"
128
- "Run a shell command under the same safe root as File System. "
129
- "Absolute paths are disabled, use relative paths. "
130
- f"Detected shell: {_DETECTED_SHELL_NAME}. "
131
- "</div>"
132
- ),
133
- api_description=TOOL_SUMMARY,
134
- flagging_mode="never",
135
- submit_btn="Run",
136
- )
137
-
138
-
139
- __all__ = ["Shell_Exec", "build_interface"]