Eu tenho 2 computadores localpc
e remoteserver
.
Eu preciso localpc
executar alguns comandos remoteserver
. Uma das coisas que ele precisa fazer é iniciar um script de backup que seja executado por várias horas. Eu gostaria que o comando localpc
"disparasse" e depois continuasse sendo totalmente independente remoteserver
, como localpc
se nunca estivesse lá em primeiro lugar.
Isto é o que eu fiz até agora:
remoteserver
contém possui o script:
/root/backup.sh
localpc
está programado para executar isso:
ssh root@remoteserver 'nohup /root/backup.sh' &
Estou fazendo isso da maneira certa? Existe uma maneira melhor de fazer isso? Terei algum problema em fazê-lo desta maneira?
ssh
scripting
nohup
background-process
LVLAaron
fonte
fonte
Respostas:
Você provavelmente deve usar
screen
no host remoto, para ter um comando desanexado real:fonte
Perto, mas não exatamente.
Independentemente de qualquer terminal
Você precisa fechar todos os descritores de arquivo conectados ao soquete ssh, porque a sessão ssh não será fechada enquanto algum processo remoto tiver o soquete aberto. Se você não estiver interessado na saída do script (presumivelmente porque o próprio script cuida da gravação em um arquivo de log), redirecione-o para
/dev/null
(mas observe que isso ocultará erros como não conseguir iniciar o script).O uso
nohup
não tem efeito útil aqui.nohup
organiza o programa que é executado para não receber um sinal HUP se o terminal de controle do programa desaparecer, mas aqui não há terminal em primeiro lugar, então nada enviará um SIGHUP para o processo do nada. Além disso,nohup
redireciona a saída padrão e o erro padrão (mas não a entrada padrão) para um arquivo, mas apenas se eles estiverem conectados a um terminal, o que, novamente, não estão.Desconectando de um terminal
Use
nohup
para desanexar o script de seu terminal de controle para que ele não receba um SIGHUP quando o terminal desaparecer.nohup
também redireciona a saída padrão do script e o erro padrão para um arquivo chamadonohup.out
se estiver conectado ao terminal; você mesmo deve cuidar da entrada padrão.Mantendo um terminal remoto
Se você deseja manter o comando em execução em um terminal remoto, mas não o anexa à sessão SSH, execute-o em um multiplexador de terminal, como Screen ou Tmux .
Posteriormente, você pode reconectar-se ao terminal em que o script está executando, invocando
screen -S backup -rd
como root nessa máquina.Automatizando um Comando Remoto
Para uma segurança um pouco melhor, não abra logins remotos remotos diretos demais. Crie um par de chaves para fins especiais e dê a ele um comando forçado
/root/.ssh/authorized_keys
. O conteúdo do arquivo de chave pública éAAAA…== [email protected]
; adicione uma lista de opções separadas por vírgula, incluindo ascommand="…"
que especificam que a chave pode ser usada apenas para executar este comando específico. Certifique-se de manter as opções e a chave em uma linha.fonte
-f
opção de obter ssh para 'background' (ou seja, encerrar, fechar conexões) no lado local. Isso funcionará em conjunto com o&
.nohup
é opcional neste caso, mas você pode considerar o usosetsid
.A receita padrão para executar um comando remoto a partir de um login remoto como SSH é a seguinte:
Se
command
é um script de shell que cuida do log de um arquivo em si, você pode alterarcommand.log
para/dev/null
. Depois de iniciar isso, faça logoff imediatamente.Você precisa de tudo nessa linha.
nohup
informa ao shell para não atrapalhar o processo se a sessão de login estiver desconectada.</dev/null
diz para nunca esperar pela entrada>command.log
diz para enviar qualquer mensagem para esse arquivo de log nomeado2>&1
diz para enviar quaisquer mensagens stderr para o mesmo arquivo de log. Em alguns casos, é melhor ter dois arquivos, o segundo para coletar mensagens de erro e o primeiro para coletar mensagens de atividade normal. Isso pode facilitar a verificação de que tudo funcionou corretamente.&
diz para desanexar esse processo e executá-lo em segundo plano como um processo daemon.fonte
Esse tópico foi muito útil, mas minha solução tinha que ser um pouco diferente.
Eu não gosto da solução de tela porque deixa um processo de tela em execução do qual não preciso. Os redirecionamentos e nohups usados assim:
NÃO estavam trabalhando para mim quando usados com o comando ssh.
Criei um script de wrapper na máquina remota que executa o script real. O script do wrapper define o redirecionamento e o nohup. Algo assim:
Em seguida, na minha máquina cliente, eu corro (observe sem redirecionamento):
O comando ssh retorna imediatamente, a conexão é encerrada e o script permanece em execução.
fonte
Como Nils diz , é um risco de segurança permitir que o root efetue login via ssh. E eu aconselho a não executar nenhum trabalho substancial em uma máquina sem um log. Se algo der errado, você desejará ter algumas mensagens de solução de problemas. Existem outras respostas mostrando como fazer isso. Mas aqui está como eu recomendo realizar exatamente o que você pediu. Está tudo embutido no sh (1). Não há necessidade de tela GNU (embora eu ache que seja uma solução inteligente). Anexar esta cadeia para o seu comando:
>&- 2>&- <&- &
.>&-
significa fechar stdout.2>&-
significa stderr próximo.<&-
significa stdin próximo.&
significa executar em segundo plano, por exemplofonte
Você deve colocar o comando remoto em segundo plano
remoteserver
. A maneira como você faz isso fará o segundo plano do comando sshlocalpc
.Além disso, é uma má idéia permitir o root-ssh.
Então, configure
remoteserver
: Uma linha de sudoers que será executada/root/backup.sh
como root pelo usuáriobackup
.Você pode criar esse usuário sem uma senha "boa".
Coloque o comando
sudo /root/backup.sh &
como comando em~backup/.ssh/authorized_keys
- junto com a chave pública delocalpc
(quem quer que acione esse script).fonte
fonte