Gnu 屏幕:在附加时执行命令

San*_*dro 7 shell-script gnu-screen

有没有办法让 GNU Screen 在它被附加时检测它并在它被附加时执行我拥有的 shell 脚本?这样做的原因是我想保持 X11 转发的显示变量正确,但我需要检测屏幕何时重新连接到另一台计算机以触发我的脚本。

谢谢。

Gil*_*il' 4

您可以在附加之前运行screen -S foo -X setenv DISPLAY "$DISPLAY"; screen -S foo -rd以更改进程的环境screen。这不会影响现有的窗口。

您也许可以将 shell 配置为在每次显示提示时检查更新DISPLAY(以及任何其他相关变量,例如)。(这意味着,如果附加会话时 shell 处于提示符处,XAUTHORITY您可能必须按一次。)Bash在显示每个提示符之前进行评估。Zsh 在显示每个提示之前运行该函数。例如,如果您已将所需的环境分配放入脚本中(其中 12345 是屏幕进程的 pid,并且是会话名称),则可以使用类似的内容(对于 zsh,未经测试;我不认为您'无需在 bash 中分叉就可以逃脱):Enter$PROMPT_COMMANDprecmd~/var/run/screen-12345.foo.env-update.shfoo

precmd () {
  local now=$SECONDS
  set ~/var/run/"screen-$STY.env-update.sh"(Nms-$(($now-$screen_env_time)))
  if [[ $# -ne 0 ]]; then
    screen_env_time=$now
    . ~/var/run/"screen-$STY.env-update.sh"
  fi
}
Run Code Online (Sandbox Code Playgroud)

在某些操作系统上,您可以从$PROMPT_COMMAND或做的另一件事是读取父进程的环境(这假设您已经更新了屏幕进程的环境)。precmd例如,在 Linux 上使用 zsh(仅当在屏幕下运行时才执行此操作):

precmd () {
  local record
  while read -r -d $'\0' record /proc/$PPID/environ; do
    case ${record%%=*} in
      DISPLAY|XAUHORITY) export $record;;
    esac
  done
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,您可以使用调试器更改另一个进程的环境。但它很有可能使该进程崩溃,因为程序的内部数据结构与内核保存的数据不匹配。

请注意,如果您在屏幕窗口内运行 ssh,这些解决方案都不会起到任何作用。