终端窗口Resize时自动重新执行历史命令的Bash实现方法
实现Bash终端Resize时自动重新执行历史命令
这个需求确实实用——谁没遇到过把终端拉宽后,之前的ls输出还是挤成一团的尴尬?下面我就一步步带你实现这个功能,全程基于Bash,不需要额外工具。
核心思路
终端窗口大小变化时,系统会给Shell发送SIGWINCH信号。我们可以利用Bash的trap机制捕捉这个信号,触发自定义逻辑:重新执行最近一次适合窗口宽度的命令。
具体实现步骤
1. 记录最近执行的命令
首先得把用户最后执行的命令存下来,方便窗口变化时调用。Bash的PROMPT_COMMAND变量会在每次显示命令提示符前执行,刚好用来更新这个记录:
# 定义变量存储最后一条命令 last_cmd="" # 每次显示提示符前,提取历史记录的最后一条并保存(去掉行号和空格) PROMPT_COMMAND='last_cmd=$(history 1 | sed -E "s/^[[:space:]]*[0-9]+[[:space:]]*//")'
2. 定义允许自动刷新的命令白名单
不是所有命令都适合自动重新执行(比如rm、cd这类有副作用或和窗口无关的命令),我们得定义一个安全的白名单:
# 允许自动刷新的命令(可根据自己需求添加/修改) allowed_cmds=("ls" "ll" "la" "ps" "df" "du" "tree" "exa")
比如你常用exa替代ls,直接把它加进去就行。
3. 编写信号处理函数
接下来写一个处理SIGWINCH信号的函数,它会检查最后一条命令是否在白名单里,如果是就重新执行:
resize_refresh() { # 没有记录到命令就直接返回 [[ -z "$last_cmd" ]] && return # 提取命令的第一个单词(比如"ls -la"中的"ls") cmd_name=$(echo "$last_cmd" | awk '{print $1}') # 检查命令是否在白名单中 if [[ " ${allowed_cmds[@]} " =~ " ${cmd_name} " ]]; then # 清屏(可选,让输出更整洁) clear # 打印提示并重新执行命令 echo "[$(date +'%H:%M:%S')] 自动重新执行: $last_cmd" eval "$last_cmd" fi }
4. 绑定信号处理函数
最后把resize_refresh函数绑定到SIGWINCH信号上,让窗口变化时自动触发:
# 捕捉窗口大小变化信号,触发刷新逻辑 trap resize_refresh SIGWINCH
让配置永久生效
上面的代码直接在终端执行的话,关闭终端就失效了。要永久生效,把所有代码添加到你的~/.bashrc或~/.bash_profile文件末尾,然后执行source ~/.bashrc即可。
注意事项
- 安全第一:务必确保白名单里的命令都是无副作用的,绝对不要加
rm、mv、curl这类可能修改文件或发送请求的命令。 - 复杂命令兼容:如果你的命令包含管道、重定向(比如
ls | grep txt),eval也能正确处理,但要确保这些命令重复执行是安全的。 - 自定义调整:不想清屏就删掉
clear;不想显示提示信息就去掉echo那一行,完全按自己习惯来。
内容的提问来源于stack exchange,提问作者Sriteja Sugoor
相关产品推荐
相关产品推荐

