Files
ZDTT/zdtt/shell.py
Zane V a9d4d98c4c Refactor terminal.py to enhance plugin management and system compatibility
- Moved various functions related to plugin validation and quarantine to the zdtt.plugins module for better organization and reusability.
- Updated the handling of protected commands to source from the plugins module.
- Refactored status bar management functions to utilize the zdtt.status_bar module, improving code clarity and separation of concerns.
- Simplified the display banner and compatibility warning functions by delegating to the zdtt.ui module.
- Enhanced the command execution process by integrating shell command execution from the zdtt.shell module.
2025-11-16 10:47:24 -05:00

83 lines
2.5 KiB
Python

"""
System shell command execution utilities for ZDTT.
"""
import sys
import subprocess
import time as time_module
def execute_system_command(terminal, command: str):
"""Execute a system command with real-time I/O streaming."""
status_bar_was_running = terminal.status_bar_thread and terminal.status_bar_thread.is_alive()
try:
process = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=sys.stdin,
bufsize=1,
text=True,
cwd=terminal.current_dir
)
early_output = []
start_time = time_module.time()
check_timeout = 0.1
hide_output = False
output_buffer = []
try:
while True:
char = process.stdout.read(1)
if not char:
if process.poll() is not None:
break
time_module.sleep(0.01)
continue
if time_module.time() - start_time < check_timeout:
early_output.append(char)
combined = ''.join(early_output).lower()
if 'command not found' in combined or 'not found:' in combined:
hide_output = True
while process.poll() is None:
process.stdout.read(1)
break
output_buffer.append(char)
if char == '\n' or len(output_buffer) >= 1024:
if not hide_output:
sys.stdout.write(''.join(output_buffer))
sys.stdout.flush()
output_buffer.clear()
if output_buffer and not hide_output:
sys.stdout.write(''.join(output_buffer))
sys.stdout.flush()
process.wait()
except BrokenPipeError:
pass
except KeyboardInterrupt:
try:
if 'process' in locals():
process.terminate()
process.wait(timeout=1)
except Exception:
try:
if 'process' in locals():
process.kill()
except Exception:
pass
print("\n^C")
except Exception as e:
if not locals().get('hide_output', False):
print(f"{terminal.COLOR_ERROR}Error executing command: {e}{terminal.COLOR_RESET}")
finally:
if status_bar_was_running:
terminal._render_status_bar()