You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zsh子shell循环中sleep的替代方案及窗口大小监听优化

Zsh/curses窗口大小自动调整的优化方案

问题背景

使用Zsh 5.9(macOS/Ubuntu环境)结合zsh/curses开发命令行界面时,希望窗口大小变化时自动调整视图。尝试过SIGWINCH信号陷阱但无效,改用后台shell循环检测窗口尺寸并发送SIGUSR1触发刷新,但循环中的sleep命令每次都会创建新进程,缩短睡眠时长又会导致进程频繁生成,需要更高效的实现方式。

方案一:用Zsh内置命令替代外部sleep

Zsh的read命令支持-t参数设置超时,属于内置命令,不会创建额外进程。只需把monitorwindowsize函数中的sleep 0.1替换为read -t 0.1 < /dev/null即可解决进程频繁创建的问题。

修改后的monitorwindowsize函数:

monitorwindowsize ()
{
    currentLines=$LINES
    currentColumns=$COLUMNS
    while true; do
      if (( currentLines != LINES || currentColumns != COLUMNS )); then
        currentLines=$LINES
        currentColumns=$COLUMNS
        kill -SIGUSR1 $1
      fi
      # 用内置read替代外部sleep,无额外进程开销
      read -t 0.1 < /dev/null
    done
}

说明:< /dev/null用于避免read从标准输入读取内容,确保后台循环稳定运行。

方案二:修复SIGWINCH陷阱(更优方案)

之前SIGWINCH陷阱无效,大概率是因为没有手动更新LINES和COLUMNS变量(Zsh不会在收到SIGWINCH时自动刷新这两个值),或者陷阱设置时机不对。以下是修复后的完整代码:

#!/bin/zsh

zmodload zsh/curses

view ()
{
    zcurses addwin mywin $(( LINES-4 )) $(( COLUMNS-4 )) 2 2 
    zcurses clear mywin
    zcurses border mywin
    zcurses refresh mywin
    zcurses move mywin $(( (LINES-4)/2 )) $(( (COLUMNS-8)/2 ))
    zcurses string mywin "Box"
    zcurses refresh mywin
}

resetview ()
{
    zcurses end
    tput clear
    # 手动获取终端尺寸并更新LINES/COLUMNS
    eval $(stty size | awk '{print "LINES="$1"; COLUMNS="$2}')
    # 避免窗口不存在时的报错
    zcurses clear mywin 2>/dev/null || true
    zcurses delwin mywin 2>/dev/null || true
    view
}

# SIGWINCH信号处理函数
TRAPWINCH() {
    resetview
}

TRAPINT() {
    zcurses end
    exit
}

zcurses init
view

# 主循环等待事件,无额外进程
while true; do
    read -t 1000
done

zcurses end

说明:

  1. 在resetview中通过stty size获取当前终端的行和列数,手动更新LINES和COLUMNS变量。
  2. 将SIGWINCH陷阱设置在zcurses init之后,确保终端模式初始化完成。
  3. 去掉后台的monitorwindowsize进程,直接通过系统SIGWINCH信号触发视图调整,完全消除额外进程开销。

效果演示

窗口调整效果演示

内容的提问来源于stack exchange,提问作者user18451290

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:15:42