Estou tentando determinar se um comando que estou executando está dentro de uma sessão SSH. Normalmente, isso funciona bem verificando $SSH_CONNECTION
ou percorrendo a árvore de processos e procurando por arquivos sshd
.
No entanto, se eu iniciar uma screen
sessão localmente e depois reanexá-la por meio de SSH, nenhuma dessas opções funcionará.
Existe alguma maneira de dentro da sessão de tela reanexada para determinar a qual shell a sessão está anexada no momento?
A árvore de processos se parece com shell(X) --> screen(Y) --> systemd(1)
, o que faz sentido, já que a sessão de tela provavelmente é alterada quando eu saio do terminal local.
screen -ls
não diz nada além de (Attached)
, apenas com o PID Y
, nenhum PID útil de onde está conectado no momento.
A árvore de processo de shell(A)
onde ele está anexado inclui um único filho screen(B)
, mas não consigo encontrar uma maneira de vincular os PIDs Y
e os arquivos B
. Eu até tentei encontrar a outra extremidade do soquete unix sendo usada pela tela, mas ela aparece vazia. (mesmo marcado como root
).
Isso é apenas algo que não é possível?
Depois de muita experimentação, aqui está o que eu acabei com:
Encontre a tela em que o shell está sendo executado. Continue andando no pstree até que um processo de tela seja encontrado:
screen_pid=$(pstree -psUA $$ | egrep -o 'screen\([0-9]+\)' | tail -1 | egrep -o '[0-9]+')
Veja todos os arquivos abertos para esse processo. Encontre o único arquivo /dev/pts/* nessa lista:
screen_pts=$(lsof -p $screen_pid | grep /dev/pts | awk '{print $NF}')
Encontre o processo de tela que controla esse pseudoterminal:
ps -o pid=,tty= -C screen | grep ${screen_pts/\/dev\/} | awk '{print $1}'
A partir daí, o processo pai será o shell/ssh/whatever iniciar a tela que agora está anexada ao shell.
Definitivamente, existem algumas suposições feitas aqui que "funcionam na minha máquina (tm)", mas essa é a ideia geral.
Se a confiabilidade for necessária, usar
stat
withst_rdev
eliminará a substituição hacky /dev/pts/5 -> pts/5. E algo semelhante poderia ser usado para filtrar a lista de arquivos abertos ondemajor(st_rdev)
== algum valor que representa pseudoterminais.