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)