ssh e shell através do ssh: como sair?

22

Estou lançando um script distante através do SSH assim:

ssh user@ipaddress '~/my_script.sh'

Tudo está indo bem, mas depois que o script é concluído, a conexão não é fechada. Eu tenho que pressionar CTRL-C para interromper a conexão atual.

Eu tentei o comando "exit" em '~ / my_script.sh' e é inútil. Eu tentei o comando "logout" em '~ / my_script.sh' e recebo uma mensagem:

logout: not login shell: use exit

...

Alguma idéia de como eu poderia fazer para fechar automaticamente e corretamente o SSH depois que o script for concluído?

(Modificação para esclarecimentos :) Aqui está o que está dentro do meu script:

#!/bin/sh
path_sources_qas=/sources/QuickAddress/
path_qas_bin=/usr/bin/qas

umount_disque_qas()
{
  # Umount du disque 'qas' s'il n'avait pas été 'umount' :
  nom_disque_monte=`cat /etc/mtab | grep qas | awk '{ print $2}'`
  if [ "$nom_disque_monte" != "" ]
  then
    echo "For safety, umount : $nom_disque_monte"
    umount $nom_disque_monte
  fi

}

# Umount twice (we never know if a st***d guy mounted it twice) :
umount_disque_qas
umount_disque_qas

echo "--------------------------------"
echo "Install ISO quick address..."
nom_fichier_iso=`ls -t $path_sources_qas | awk '{if (NR==1) {print $1}}'`
echo "Mount disk $nom_fichier_iso..."
mount -o loop -t iso9660 $path_sources_qas/$nom_fichier_iso /mnt/qas
echo "Done."

# All the folders are like this :
# /usr/bin/qas/Data.old.10
# /usr/bin/qas/Data.old.11
# /usr/bin/qas/Data.old.12
# ...

echo "--------------------------------"
echo "Stopping QuickAdress server..."
cd $path_qas_bin/apps/
./wvmgmtd shutdown qaserver:2021
sleep 3
echo "Done."

# Get last number of the folder:
num_dernier_dossier_backup=`ls -Atd $path_qas_bin/Data.old* | awk '{if (NR==1) {print $1}}' | awk -F . '{print $NF}'`
# Add 1 :
let "num_dernier_dossier_backup += 1"
# Full name :
nom_dossier_backup=Data.old.$num_dernier_dossier_backup
echo "--------------------------------"
echo "Saving Data to $nom_dossier_backup..."
cd $path_qas_bin
mv Data $nom_dossier_backup
echo "Done."


echo "--------------------------------"
echo "Copying new folder Data..."
cd $path_qas_bin
cp -r /mnt/qas/Data .
echo "Done."

echo "--------------------------------"
echo "Deleting unused datas..."
cd $path_qas_bin/apps/
rm -f $path_qas_bin/Data/frxmos.dap
echo "Done."

echo "--------------------------------"
echo "Restart server..."
cd $path_qas_bin/apps/
./qaswvd &
sleep 3
echo "Done."
sleep 3

echo "--------------------------------"
echo "Check: server state: you should read 'OK':"
./wvmgmtd srvlist
echo "Done."

echo "--------------------------------"
echo "Check: active licences (only one here):"
./wvmgmtd licencelistread qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: counters: number of addresses left:"
./wvmgmtd counterinforead qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: Datasets avalaibles:"
./wvmgmtd datalistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Check: "meters" for "licence by click":"
./wvmgmtd meterslistread current qaserver:2021
echo "Done."

echo "--------------------------------"
echo "Removing virtual disk..."
umount_disque_qas
echo "Done."

echo "All done"
echo "Click 'Ctrl-C' to quit."

exit

Quando o inicio através do SSH, ele é executado e, no final, eu leio "Tudo pronto". então isso significa que ele atinge as duas últimas linhas .

Alguma idéia de como eu poderia fazer para fechar automaticamente e pr

Olivier Pons
fonte
1
O que há no script?
Ignacio Vazquez-Abrams
@ Olivier: Você encaminha alguma porta (incluindo o agente e o X)? A conexão ssh é fechada quando o comando termina e todas as conexões TCP foram fechadas.
Gilles 'SO- stop be evil'
@ Gilles: não, eu apenas faço uma conexão shell para executar um script, nada é encaminhado.
perfil completo de Olivier Pons
1
@ Oliver: Se você tiver um ~/.ssh/config, tente sem ele e passe as opções -a -x(e não -o) sshpara garantir que não haja encaminhamento. Se ainda assim não funcionar, mostre o conteúdo do script.
Gilles 'SO- stop be evil'
@ Oliver: o script inicia algum trabalho em segundo plano que pode estar esperando? Infelizmente, os trabalhos não parecem retornar nada quando em um script ssh. Exemplo: ssh <yourusername>@localhost '(ls; sleep 10 &); echo Done; jobs'irá listar arquivos, exibir pronto e aguardar 10 segundos antes de retornar.
asoundmove

Respostas:

19

A saída no script do shell não funciona porque está saindo do script, não do shell. Para sair do shell após a conclusão do script, faça

ssh user@ipaddress '~/my_script.sh && exit'

Isso executará o script e sairá do shell.

Wuffers
fonte
3
Deveria estar saindo. O script é o shell.
Pausado até novo aviso.
@ Dennis: Não está funcionando para ele, então isso pode funcionar.
Wuffers 5/11/10
2
@Sr. Homem: Seu comando é equivalente ao original, exceto que ele força um shell a existir entre sshde o shell em execução myscript.sh. O que exitvocê escreveu atuará quando o script sair, o que não ajuda. A única maneira de sua solução funcionar é se o script faz algo bizarro quando seu pai é sshde não faz essa coisa bizarra quando seu pai é um shell.
Gilles 'SO- stop be evil'
Como isso não ajuda? A saída fechará o shell e encerrará a conexão, correto? E não é isso que o pôster quer fazer?
Wuffers 5/11
3
@ MrMan: ~/my_script.sh && exitsai assim que ~/my_script.shsai. Se o script do shell não sair, seu comando nunca chegará ao ponto exit. Então é apenas inútil.
Gilles 'SO- stop be evil'
12

A conexão ssh permanece aberta quando o processo iniciado pelo ssh (aqui, um shell) termina, se houver outros processos que ainda a estejam usando. Não sei as regras exatas que o daemon ssh segue, mas uma conexão está em uso, pelo menos, se a saída padrão de qualquer processo filho ainda estiver conectada ao pipe original fornecido pelo ssh. Comparar:

ssh somehost 'sleep 5 &'  # exits after 5 seconds
ssh somehost 'sleep 5 >/dev/null &'  # exits immediately seconds

Ao iniciar um daemon, você deve colocá-lo em segundo plano e fechar seus descritores de arquivo. Pelo menos, use isto:

./qaswvd </dev/null >/dev/null 2>/dev/null &

Você pode adicionar nohupna frente; não fará diferença aqui, mas seria útil se o script fosse executado em um terminal. Muitos programas projetados para agir como daemon têm opções de linha de comando para fazer com que bifurcem, fechem descritores de arquivos, ignorem sinais e outros detalhes. Verifique na qaswvddocumentação se ela possui uma. Você também pode investigar os utilitários do "daemonizer".

Gilles 'SO- parar de ser mau'
fonte
Teve o mesmo problema, e isso funciona. A resposta aceita não funciona.
21418 Andy
5

Vi este post quando pesquisei a solução da mesma situação. Embora seja meio tarde para resolver o problema de @ Oliver, já que a resposta aceita claramente não estava funcionando para o OP ou para mim (não sei por que ela foi aceita), eu ainda gostaria de postar minha própria solução para futuros googler. É simples: adicione uma -fopção no sshcomando:

ssh -f user@ipaddress '~/my_script.sh'

EDITAR

O efeito da -fopção é colocar sshem segundo plano, portanto, sem nenhuma opção adicional adicionada, é possível que a conexão ainda esteja viva, mesmo que pareça que está quebrada. Pode-se consultar a resposta dada em outro post neste site, se estiver interessado.

Leo Fang
fonte
Cuidado: Este (-f) não funcionará se o script original tiver prompt (s) para entrada do usuário.
madD7
3

Como Ignacio, estou curioso para saber o que está no seu script.

Talvez você possa tentar reduzir seu script ao menor exemplo possível que produz a condição de erro.

Ou comece com um script vazio e adicione um comando de cada vez até ver o problema, para saber qual comando faz com que seu script seja bloqueado.

Se o script vazio causar um problema, você pode investigar sua configuração ssh, por exemplo, é .bash_logout ou algo chamado na saída que pode causar um problema?

asoundmove
fonte
Obrigado pela sua sugestão, agora adicionamos o exemplo do meu script na minha pergunta.
Olivier Pons
@ Olivier: Você adicionou apenas partes irrelevantes do seu script. Poste um script (e instruções de uso, se necessário) que permitirão que os leitores reproduzam seu problema . Simplifique o script o máximo possível, mas não mais.
Gilles 'SO- stop be evil'
@Gilles Obrigado. Modifiquei minha pergunta e adicionei o script inteiro. Espero que isto ajude. Parece que o problema pode ser o fato de eu estar iniciando um processo em segundo plano ( a linha "./qaswvd &" ). Essa poderia ser a origem do problema?
Olivier Pons
1
@ Olivier: Sim, seu processo principal aguardará o processo em segundo plano parar antes de sair. Se você quiser que algo continue em execução depois de sair, tente nohup. Não tenho certeza se funciona com ssh, mas experimente que não vai doer.
asoundmove
2

Você provavelmente pode usar trabalhos em seu script. Se for esse o caso, o shell apenas espera que seus trabalhos sejam concluídos e não deseja se desconectar.

Não vou repostar, apenas encaminhá-lo-á http://en.wikipedia.org/wiki/Nohup#Existing_jobs

Oleksiy Khilkevich
fonte
Modifiquei minha pergunta e adicionei o script inteiro. Espero que isto ajude. Parece que o problema pode ser o fato de eu estar iniciando um processo em segundo plano (a linha "./qaswvd &"). Se você estiver certo, isso pode ser a origem do problema?
Olivier Pons
O processo em segundo plano é o problema, mas nohupnão é diretamente o problema aqui, pois não há terminal no lado do servidor: acho que o culpado é especificamente o descritor de arquivo aberto.
Gilles 'SO- stop be evil'
Sim, acho que esse é o problema, você pode tentar comentar ou aplicar o hack no link acima #
Oleksiy Khilkevich
1

Você precisará matar o processo pai de dentro do seu script.

kill -SIGHUP $PPID

OmnipotentEntity
fonte
0

O problema provavelmente é a seguinte linha.

./qaswvd &

Este comando provavelmente ainda está em execução e manterá o pipe ssh aberto até que stdin e stdout & stderr sejam fechados.

Use isto:

./qaswvd </dev/null >/dev/null 2>&1 &
edirks
fonte