Executar comando ssh remoto com o Shell de logon completo

48

Eu gostaria de fazer algo como ssh example.com 'ls'No entanto por página de manual do ssh:

Se o comando for especificado, ele será executado no host remoto em vez de no shell de logon.

Então o que acontece é que lsexibe sua saída e o ssh sai.

O que não consigo descobrir é como abrir o shell de login completo e executar o comando dentro desse shell. Deixando o shell aberto após a execução do comando. Como se eu tivesse feito manualmente o seguinte:

  localhost$ ssh example.com 
example.com$ ls
             /folder1 
             /folder2 
example.com$ _

Alguma ideia?

Mateus
fonte
esta é uma pergunta semelhante superuser.com/questions/261617/… mas nenhuma das respostas parece realmente se encaixar no que estou tentando fazer.
matthew
Que tal ssh example.com 'ls;bash'?
Andrejs Cainikovs
você precisa do -i nos meus sistemas para tornar o segundo shell interativo.
Flexo
opção -t é a resposta para sua pergunta. Existem outras opções (por exemplo, chaveiro), mas dependem de suas reais necessidades, que não são suficientemente claras para mim.
hornetbzz
@hornetbzz -t me dá pseudo-tty. Mas, caso contrário, o comportamento é o mesmo. Quero iniciar um shell interativo, executar um comando dentro desse shell e manter o shell aberto após a execução do comando.
matthew

Respostas:

40

Apenas diga ao bash para executar lse depois em um shell de login

$ ssh user@host  -t 'bash -l -c "ls;bash"'
fons
fonte
2
Infelizmente, isso não parece funcionar durante o uso screen. Caso contrário, isso parece fazer o que eu estava tentando fazer.
matthew
31
ssh user@host -t 'ls; exec $SHELL -l'

-tForçar alocação pseudo-terminal. Isso pode ser usado para executar programas arbitrários baseados em tela em uma máquina remota. É um pouco mais adequado que bash -i.

exec Nenhum novo processo é criado.

-lprocura por ~ / .bash_profile, ~ / .bash_login e ~ / .profile, nessa ordem, e lê e executa comandos a partir de ... Sem isso, você provavelmente não pode executar scripts / comandos a partir do diretório ~ / bin, porque esse código from ~ / .profile não será executado sem o -lsinalizador:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
gravidade
fonte
@grawity @Alan Isso pode funcionar como uma solução alternativa, mas eu realmente gostaria que o comando fosse executado dentro do shell e não apenas abra um novo shell após a execução do comando.
matthew
+1, -t é definitivamente o caminho certo para ultrapassar -i, acabei de me esquecer disso.
Flexo
@ Matthew: Você terá que se consertar bashpara permitir isso.
grawity
@Grawity não realmente, veja a minha resposta abaixo #
fons
@matthew, use exec bashorexec $SHELL
Eugen Konkov #
1

No seu comentário sobre a resposta de fons, você diz que não funciona durante o uso screen.

Você poderia elaborar sobre isso? Observando o código-fonte do openssh, o sshd executa o comando chamando

YOUR_DEFAULT_SHELL -c COMMAND

Portanto, por exemplo, se o seu shell padrão for screen, isso não funcionará muito bem porque screeno -csinalizador simplesmente substitui o seu .scrreenrc. Portanto, não há realmente nenhuma maneira de enviar comandos para a tela, se for seu shell padrão. Você precisará executar a tela como o comando dado ao ssh, mas com um shell padrão que não é a tela .

Se é isso que você está tentando fazer, acho que as coisas ficarão realmente estranhas, já screenque também fechará janelas com programas não interativos, então você terá que fazer um truque semelhante ao de fons, mas um nível mais profundo. SO, com, por exemplo, / bin / bash (e não tela) como seu shell padrão .

ssh user@host -t 'screen bash -l -c "ls;bash"'

O que deve - respirar fundo - ssh no host, execute bash -c com um comando de tela, que abrirá uma nova janela. Se essa janela apenas abrisse ls, ela terminaria e a tela terminaria, então usamos o truque de fons dentro da nova janela da tela .

Eu acho que vai funcionar, se é isso que você estava tentando fazer;)

Scott Walls
fonte
Penso que o problema que tenho screennesta situação é que normalmente o carrego exec screen -RRdo meu .profile. Isso significa que bash -ltenta carregar a tela que descarta o resto. parece que posso contornar isso removendo '-l' nas suas soluções e @fons (a sua então me deixa screen). É meio que vacilante.
matthew
0

Várias opções -t forçam a alocação de tty, mesmo se ssh não tiver tty local:

ssh -tt user@host 'bash -l -c "/path/to/command'
panticz.de
fonte