Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import subprocess | |
| from typing import Tuple | |
| import os | |
| # Security: Define allowed commands or use a whitelist approach | |
| DANGEROUS_COMMANDS = ['rm -rf /', 'dd if=', 'mkfs', ':(){ :|:& };:'] | |
| async def run_command(command: str) -> Tuple[str, str]: | |
| """ | |
| Run a command on shell with improved security and error handling. | |
| Args: | |
| command: Shell command to execute | |
| Returns: | |
| Tuple of (output, status_message) | |
| """ | |
| if not command or not command.strip(): | |
| return "", "โ Error: Empty command provided" | |
| # Basic security check for obviously dangerous commands | |
| for dangerous in DANGEROUS_COMMANDS: | |
| if dangerous in command: | |
| return "", f"๐ซ Security: Command blocked (contains: {dangerous})" | |
| try: | |
| # Use subprocess instead of os.popen for better control | |
| result = subprocess.run( | |
| command, | |
| shell=True, | |
| capture_output=True, | |
| text=True, | |
| timeout=30, # Prevent hanging commands | |
| cwd=os.getcwd() | |
| ) | |
| # Combine stdout and stderr | |
| output = result.stdout | |
| if result.stderr: | |
| output += f"\n--- STDERR ---\n{result.stderr}" | |
| if result.returncode == 0: | |
| status = f"โ Success (exit code: {result.returncode})" | |
| else: | |
| status = f"โ ๏ธ Command exited with code: {result.returncode}" | |
| return output or "(no output)", status | |
| except subprocess.TimeoutExpired: | |
| return "", "โฑ๏ธ Error: Command timed out (30s limit)" | |
| except Exception as e: | |
| return "", f"โ Error: {str(e)}" | |
| def create_interface(): | |
| """Create the Gradio interface with improved UI""" | |
| with gr.Blocks( | |
| title="Shell Command Executor", | |
| ) as demo: | |
| gr.Markdown(""" | |
| # ๐ฅ๏ธ Shell Command Executor | |
| Execute shell commands safely with timeout protection and error handling. | |
| **โ ๏ธ Warning**: Use with caution. Some dangerous commands are blocked. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| command_input = gr.Textbox( | |
| label="Command", | |
| placeholder="Enter your shell command (e.g., ls -la, pwd, echo 'hello')", | |
| lines=2 | |
| ) | |
| with gr.Row(): | |
| run_btn = gr.Button("โถ๏ธ Run Command", variant="primary") | |
| clear_btn = gr.Button("๐๏ธ Clear") | |
| with gr.Column(scale=1): | |
| status_output = gr.Textbox( | |
| label="Status", | |
| lines=2, | |
| interactive=False | |
| ) | |
| output_display = gr.Code( | |
| label="Output", | |
| language="shell", | |
| lines=15 | |
| ) | |
| gr.Markdown(""" | |
| ### ๐ Example Commands | |
| - `pwd` - Print working directory | |
| - `ls -la` - List files with details | |
| - `whoami` - Show current user | |
| - `df -h` - Show disk usage | |
| - `ps aux | head -n 10` - Show top 10 processes | |
| """) | |
| # Event handlers | |
| run_btn.click( | |
| fn=run_command, | |
| inputs=command_input, | |
| outputs=[output_display, status_output] | |
| ) | |
| command_input.submit( | |
| fn=run_command, | |
| inputs=command_input, | |
| outputs=[output_display, status_output] | |
| ) | |
| clear_btn.click( | |
| fn=lambda: ("", "", ""), | |
| outputs=[command_input, output_display, status_output] | |
| ) | |
| return demo | |
| if __name__ == "__main__": | |
| print("๐ Starting Shell Command Executor...") | |
| print("โ ๏ธ Security features enabled: timeout protection, basic command filtering") | |
| demo = create_interface() | |
| demo.launch( | |
| mcp_server=True, | |
| show_error=True) |