Ok, eu percebi. Esta é realmente uma coisa muito bacana de saber, como posso prever ter muitos usos.
-
abra uma sessão ssh no host remoto. Inicie uma tela ou sessão tmux com algumas janelas. Você pode determinar o pseudo-dispositivo para cada janela digitando "tty". Digamos que temos "/ dev / pts / [123]" correspondente a três shells que estamos executando na sessão de tela
-
determine o pid do processo bash em questão (aquele para o qual você quer redirecionar entrada e saída). este processo está atualmente associado a um dispositivo de terminal como / dev / tty1
-
da janela de tela 1, execute "gdb -p [pid]" e execute os seguintes comandos no gdb:
a. p dup2 (open ("/ dev / pts / 2", 0), 0) # isto muda a entrada padrão para o processo alvo
b. p dup2 (open ("/ dev / pts / 3", 1), 1) # isto muda a saída padrão para o processo alvo
c. p dup2 (open ("/ dev / pts / 3", 1,), 2) # isto muda o erro padrão para o processo alvo
d. desanexar
e. sair
em outras palavras, o que a etapa 3 faz é tornar a janela 2 a entrada padrão e a janela 3 a saída.
4.da janela 1 (/ dev / pts / 1), "ls -l / proc / [pid] / fd" para verificar as alterações do descritor de arquivo para o processo bash que queremos manipular
5.o que você digita na janela 2 agora é alimentado em dois lugares: o shell bash original associado a essa janela e o processo de destino. portanto, na janela 2 (/ dev / pts / 2), digite "hhiissttoorryy [return] [return]". o motivo pelo qual você precisa digitar tudo duas vezes é porque a entrada é dividida para o shell bash atual e o shell bash de destino. Isso ocorre porque o operador sabe que há duas fontes que estão tocando na entrada do teclado para / dev / pts / 2 e distribui de forma justa os caracteres digitados. o primeiro caractere vai para um destino, o próximo vai para o segundo destino, etc. Se você tivesse três processos cujo stdin era / dev / pts / 3, você teria que digitar cada caractere três vezes. O kernel alimenta os caracteres de entrada no modo round-robin para os destinatários.
6. Você pode contornar o inconveniente acima, definindo temporariamente o stdin para o shell bash original do Windows 2 para algum dispositivo não utilizado, como / dev / tty5 ou algo assim. isso faz com que o teclado / dev / pts / 2 seja a entrada padrão para apenas um processo (em vez de dois). Agora você pode digitar os comandos como normais (eles simplesmente não serão ecoados na tela em que você está, eles serão ecoados para / dev / pts / 3).
7. uma vez que você digitou 'history' e foi alimentado para o processo de destino, cujo stdout é a janela 3, mude para a janela 3 para que você possa ver a saída do comando. agora você tem o histórico de comandos para o shell bash de destino.
8. volte à janela 1, use gdb novamente em [pid] para redefinir o padrão in, out, err para o shell de destino de volta para seus valores originais (/ dev / tty1). E você também pode definir o stdin da Janela 2 de volta para o que deveria ser.
- Se quiser, você pode limpar os descritores de arquivos extras removendo-os com 'exec 3 > & -' para remover o fd 3, por exemplo
Observe que, quando você executa o gdb em um processo em execução, ele suspende a execução do processo da mesma maneira que o SIGSTOP. Quando você o "desconecta", ele retorna como no SIGCONT. Isso permite manipular os descritores de arquivos sem consequências adversas.
Eu não tentei, mas provavelmente você pode tornar o acima exposto ainda mais fácil e amigável ao abrir um shell, determinando seu tty ou pty, temporariamente definindo o padrão atribuído do shell para um dispositivo não-utilizado, atribuindo o tty / pty como padrão in / out para o shell de destino. Dessa forma, você pode usar uma única tela para todas as entradas e saídas com o shell de destino.
RESUMO: com o procedimento acima, desde que você tenha um shell para o qual tenha acesso, você pode usá-lo como entrada / saída padrão para qualquer outro processo / shell no sistema. Isso é útil, por exemplo, se você quiser interagir com um shell em execução no console, mas não tiver acesso físico ao host (ou a uma solução sem iluminação). Isso, obviamente, pode ser generalizado para qualquer número de situações em que você deseja que um shell específico assuma o controle da entrada / saída para qualquer processo de sua escolha.