確定呼叫螢幕重新附加的 shell
我正在嘗試確定我正在執行的命令是否在 SSH 會話中。通常,通過檢查
$SSH_CONNECTION
或遍歷程序樹並尋找sshd
.但是,如果我
screen
在本地啟動一個會話,然後通過 SSH 重新連接它,那麼這些都不起作用。在重新附加的螢幕會話中是否有某種方法可以確定會話目前附加到哪個外殼?
程序樹看起來像
shell(X) --> screen(Y) --> systemd(1)
,這是有道理的,因為當我退出本地終端時,螢幕會話可能會被重新設置。
screen -ls
沒有說什麼(Attached)
,只有 PIDY
,沒有關於它目前連接位置的有用 PID。它所附加的程序樹
shell(A)
包含一個子程序screen(B)
,但我找不到連結 PIDY
和B
. 我什至試圖找到螢幕正在使用的 unix 套接字的另一端,但它是空的。(甚至檢查為root
)。這只是不可能的事情嗎?
經過大量的實驗,這就是我最終得到的結果:
- 找到執行 shell 的螢幕。繼續走 pstree 直到找到螢幕程序:
screen_pid=$(pstree -psUA $$ | egrep -o 'screen\([0-9]+\)' | tail -1 | egrep -o '[0-9]+')
- 查看該程序的所有打開文件。在該列表中找到唯一的 /dev/pts/* 文件:
screen_pts=$(lsof -p $screen_pid | grep /dev/pts | awk '{print $NF}')
- 找到控制該偽終端的螢幕程序:
ps -o pid=,tty= -C screen | grep ${screen_pts/\/dev\/} | awk '{print $1}'
- 從那裡開始,父程序將是 shell/ssh/whatever 啟動的螢幕,現在附加到 shell。
這里肯定有一些“在我的機器(tm)上工作”的駭人聽聞的假設,但這是一般的想法。
如果需要可靠性,使用
stat
withst_rdev
將消除 hacky /dev/pts/5 -> pts/5 替換。類似的東西可以用來過濾打開文件的列表,其中major(st_rdev)
== 一些代表偽終端的值。