Existe uma maneira de fazer com que o GNU Screen detecte quando ele está sendo anexado e execute um script de shell que eu tenho sempre que ele estiver anexado? A razão para isso é que quero manter minhas variáveis de exibição corretas para o encaminhamento do X11, mas preciso detectar quando a tela é reconectada a um computador diferente para acionar meu script.
Obrigado.
Responder1
Você pode executar screen -S foo -X setenv DISPLAY "$DISPLAY"; screen -S foo -rd
para alterar o ambiente do screen
processo antes de anexar. Isso não afetará as janelas existentes.
Talvez você possa configurar seu shell para verificar se há uma atualização DISPLAY
(e qualquer outra variável relevante, como XAUTHORITY
) sempre que mostrar um prompt. (Isso significa que você pode ter que pressionar Enteruma vez se o shell estava em um prompt quando você anexou a sessão.) O Bash avalia $PROMPT_COMMAND
antes de exibir cada prompt. Zsh executa a precmd
função antes de exibir cada prompt. Por exemplo, se você colocou as atribuições de ambiente desejadas em um script ~/var/run/screen-12345.foo.env-update.sh
(onde 12345 é o pid do processo de tela e foo
é o nome da sessão), você pode usar algo como (para zsh, não testado; não acho que você' serei capaz de sair sem bifurcar no bash):
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
}
Outra coisa que você pode fazer em $PROMPT_COMMAND
or precmd
, em alguns sistemas operacionais, é ler o ambiente do processo pai (isso pressupõe que você atualizou o ambiente do processo de tela). Por exemplo, no Linux com zsh (faça isso apenas se estiver executando na tela):
precmd () {
local record
while read -r -d $'\0' record /proc/$PPID/environ; do
case ${record%%=*} in
DISPLAY|XAUHORITY) export $record;;
esac
done
}
Tecnicamente, você pode alterar o ambiente de outro processo usando um depurador. Mas há uma boa chance de que esse processo trave, porque as estruturas de dados internas do programa não corresponderão aos dados mantidos pelo kernel.
Observe que nenhuma dessas soluções servirá de nada se você executar o ssh dentro de uma janela de tela.
Responder2
O que você eventualmente deseja não pode ser feito. Mesmo que você consiga que a tela execute um script na conexão, ainda não será possível alterar o ambiente dos processos filhos.
Responder3
Acho que a solução de Giles é a mais geral, mas tem duas desvantagens: (1) não funciona até que você execute um comando, após a re-anexação, e (2) o comando é executado a cada novo prompt de comando. (O que posso dizer, odeio desperdiçar ciclos de CPU). Existe uma alternativa, mas também não é perfeita: ao screen
reconectar a um terminal de tamanho diferente da janela anterior, screen
envia o SIGWINCH
sinal para o shell, que você pode capturar:
trap some_function SIGWINCH
Eu escrevi um script de shell (a ser fornecido junto com .bashrc) que explora esse fato para lidar com a reescrita do SSH_AUTH_SOCK e variáveis relacionadas ao reconectar um terminal desconectado. Veja o projeto aqui:https://gitlab.com/otheus.uibk/bashrc-ssh-agent. O script pode ser facilmente modificado para ser integrado também ao PROMPT_COMMAND.
Talvez possamos atualizar screen
com uma opção para forçar o SIGWINCH ao reconectar? Atualmente estou usando 4.1.0 (fornecido com RedHat 7), mas a versão atual é 4.6.