refactor(core): ♻️ 移除 Python PTY 转发逻辑并简化更新流程
移除复杂的 Python 脚本模拟终端逻辑,改由 brew 直接读取当前 TTY。此举解决了因新建 PTY 导致的 sudo 时间戳失效问题,并大幅精简了代码结构,提升了维护效率。 - 删除了约 80 行 Python PTY 转发引擎代码 - 优化了更新与清理任务的执行顺序 - 修复了交互式环境下权限验证的潜在冲突
This commit is contained in:
@@ -126,7 +126,7 @@ echo -e "\n${CYAN}>>> [2/2] Upgrading GUI Casks (brew cu -yaq)...${NC}"
|
||||
export HOMEBREW_COLOR=1
|
||||
|
||||
# --- 终端宽度处理 ---
|
||||
# 交互式终端里让子进程读取 PTY 的实时尺寸;非交互环境或固定宽度模式下提供 COLUMNS 兜底。
|
||||
# 交互式终端里让 brew 直接读取当前 TTY,避免 sudo 时间戳因新建 PTY 失效。
|
||||
if [[ -n "$FIXED_TERMINAL_WIDTH" || ! -t 1 ]]; then
|
||||
export COLUMNS
|
||||
COLUMNS="$(terminal_width)"
|
||||
@@ -134,91 +134,7 @@ else
|
||||
unset COLUMNS
|
||||
fi
|
||||
|
||||
# 使用 Python 原生 PTY 自建极简转发引擎。它只转发用户输入,不保存、不注入 sudo 密码。
|
||||
python3 -c '
|
||||
import pty, os, sys, select, fcntl, termios, struct, tty, signal
|
||||
|
||||
cmd = sys.argv[1:]
|
||||
pid, fd = pty.fork()
|
||||
|
||||
if pid == 0:
|
||||
os.execvp(cmd[0], cmd)
|
||||
else:
|
||||
def sync_winsize(*_):
|
||||
s = struct.pack("HHHH", 0, 0, 0, 0)
|
||||
try:
|
||||
winsize = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, s)
|
||||
rows, cols, xpix, ypix = struct.unpack("HHHH", winsize)
|
||||
if rows > 0 and cols > 0:
|
||||
fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
fallback_cols = int(os.environ.get("COLUMNS", "130") or "130")
|
||||
except ValueError:
|
||||
fallback_cols = 130
|
||||
try:
|
||||
fallback_rows = int(os.environ.get("LINES", "40") or "40")
|
||||
except ValueError:
|
||||
fallback_rows = 40
|
||||
fallback = struct.pack("HHHH", fallback_rows, fallback_cols, 0, 0)
|
||||
fcntl.ioctl(fd, termios.TIOCSWINSZ, fallback)
|
||||
|
||||
sync_winsize()
|
||||
signal.signal(signal.SIGWINCH, sync_winsize)
|
||||
|
||||
stdin_fd = sys.stdin.fileno()
|
||||
stdout_fd = sys.stdout.fileno()
|
||||
forward_stdin = sys.stdin.isatty()
|
||||
old_stdin_attrs = None
|
||||
if forward_stdin:
|
||||
old_stdin_attrs = termios.tcgetattr(stdin_fd)
|
||||
tty.setraw(stdin_fd)
|
||||
|
||||
exit_code = 0
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
watch = [fd]
|
||||
if forward_stdin:
|
||||
watch.append(stdin_fd)
|
||||
try:
|
||||
rfds, _, _ = select.select(watch, [], [], 0.1)
|
||||
except InterruptedError:
|
||||
continue
|
||||
|
||||
if fd in rfds:
|
||||
data = os.read(fd, 8192)
|
||||
if not data:
|
||||
break
|
||||
os.write(stdout_fd, data)
|
||||
|
||||
if forward_stdin and stdin_fd in rfds:
|
||||
data = os.read(stdin_fd, 8192)
|
||||
if data:
|
||||
os.write(fd, data)
|
||||
|
||||
except OSError:
|
||||
break
|
||||
|
||||
try:
|
||||
wpid, wstatus = os.waitpid(pid, os.WNOHANG)
|
||||
if wpid == pid:
|
||||
if os.WIFEXITED(wstatus):
|
||||
exit_code = os.WEXITSTATUS(wstatus)
|
||||
else:
|
||||
exit_code = 1
|
||||
break
|
||||
except ChildProcessError:
|
||||
break
|
||||
finally:
|
||||
if old_stdin_attrs is not None:
|
||||
termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_stdin_attrs)
|
||||
|
||||
sys.exit(exit_code)
|
||||
' brew cu -yaq
|
||||
brew cu -yaq
|
||||
|
||||
separator
|
||||
printf "\n"
|
||||
|
||||
Reference in New Issue
Block a user