Linux下通过PID查找窗口ID,实现gnome-terminal状态保存求助
Gnome Terminal状态保存与PID关联窗口ID解决方案
一、通过PID查找窗口ID的可行方法
以下几种方法可实现PID与窗口ID的关联,根据你的环境选择:
1. 使用xdotool(推荐,需先安装)
先安装工具:
sudo apt install xdotool
- 直接通过进程PID查找窗口ID(适用于gnome-terminal主进程):
xdotool search --pid <TARGET_PID>
- 若目标PID是标签页的shell子进程,需先获取其父进程(gnome-terminal主进程)的PID,再查找窗口ID:
gnome_pid=$(ps -o ppid= -p <SHELL_PID> | tr -d ' ') xdotool search --pid "$gnome_pid"
2. 使用wmctrl + xprop
先安装wmctrl:
sudo apt install wmctrl
- 列出所有窗口及其关联的进程PID:
wmctrl -lp
- 过滤目标PID对应的窗口ID:
wmctrl -lp | grep "<TARGET_PID>" | awk '{print $1}'
- 针对shell子进程的处理逻辑同上,先获取父进程PID再过滤。
3. 使用xwininfo
无需额外安装,直接遍历所有窗口查找关联PID的窗口:
xwininfo -root -tree | grep -B2 -A2 "<TARGET_PID>" | awk '/0x/{print $1}'
二、添加到.bashrc的终端跟踪方案
该方案通过PROMPT_COMMAND实时记录终端状态,兼容所有窗口/标签页的打开/关闭方式(快捷键、命令行、窗口按钮等):
- 将以下代码添加到
~/.bashrc末尾:
# 终端状态跟踪配置 TERM_STATE_FILE=~/.terminal_states # 每次显示命令提示符时更新当前终端状态 update_term_state() { local shell_pid=$$ # 获取当前激活窗口ID(优先用xdotool,无则用xprop) local win_id=$(xdotool getactivewindow 2>/dev/null || xprop -root _NET_ACTIVE_WINDOW | awk '{print $5}') local cwd=$(pwd) local win_title=$(wmctrl -l -x | grep "$win_id" | awk '{sub(/^[^ ]* [^ ]* [^ ]* /,""); print $0}') # 保存单个终端的状态到临时文件 echo "$shell_pid|$win_id|$cwd|$win_title|$(date +%s)" > "$TERM_STATE_FILE.$shell_pid" # 合并所有临时状态到总文件 cat "$TERM_STATE_FILE".* > "$TERM_STATE_FILE" 2>/dev/null } # 清理已退出终端的过期状态文件 clean_term_states() { for file in "$TERM_STATE_FILE".*; do local pid=$(basename "$file" | sed "s/$TERM_STATE_FILE.//") if ! kill -0 "$pid" 2>/dev/null; then rm "$file" fi done cat "$TERM_STATE_FILE".* > "$TERM_STATE_FILE" 2>/dev/null } # 绑定到命令提示符,定期清理过期状态 PROMPT_COMMAND="update_term_state; $PROMPT_COMMAND" clean_term_states
- 生效配置:
source ~/.bashrc
- 状态恢复脚本示例
创建restore_terminals.sh文件,内容如下:
#!/bin/bash TERM_STATE_FILE=~/.terminal_states # 按窗口ID分组标签页信息 declare -A window_tabs while IFS='|' read -r pid win_id cwd title ts; do window_tabs["$win_id"]+="$cwd " done < "$TERM_STATE_FILE" # 为每个窗口生成恢复命令并执行 for win_id in "${!window_tabs[@]}"; do tabs=(${window_tabs["$win_id"]}) gnome_cmd="gnome-terminal" for tab_dir in "${tabs[@]}"; do gnome_cmd+=" --tab --working-directory=\"$tab_dir\"" done eval "$gnome_cmd" & done
赋予执行权限并运行:
chmod +x restore_terminals.sh ./restore_terminals.sh
内容的提问来源于stack exchange,提问作者Sam Kent
相关产品推荐
相关产品推荐

