Como faço para desligar um servidor Linux depois de executar por 60 minutos?

17

Eu tenho um servidor que normalmente está desativado por motivos de segurança. Quando eu quero trabalhar nele, eu o ligo, executo minhas tarefas e o fecho novamente. Minhas tarefas geralmente não levam mais que 15 minutos. Eu gostaria de implementar um mecanismo para desligá-lo automaticamente após 60 minutos.

Eu pesquisei como fazer isso com o cron, mas não acho que seja a maneira correta, porque o cron não leva em consideração quando o servidor foi ligado pela última vez. Só posso definir padrões periódicos, mas eles não levam esses dados em consideração.

Como eu poderia fazer essa implementação?

    
por jmhostalet 02.10.2018 / 12:10

10 respostas

23

Se você executar suas tarefas como o mesmo usuário todas as vezes, você pode simplesmente adicionar o comando shutdown, opcionalmente com a opção -P, ao seu perfil. O número representa a quantidade de minutos que o comando de desligamento está atrasado. Certifique-se de que seu usuário tenha a capacidade de executar o comando de desligamento via sudo sem uma senha.

echo "sudo shutdown -P +60" >> ~/.profile
    
por 02.10.2018 / 12:21
67

Existem várias opções.

  • Forneça tempo diretamente para shutdown -P :

    shutdown -P +60
    

    Observe que shutdown página do manual também aponta:

    If the time argument is used, 5 minutes before the system goes down the /run/nologin file is created to ensure that further logins shall not be allowed.

  • Use o comando at .

  • Crie um arquivo de unidade do systemd ou < strong> script de inicialização que executa shutdown -P 60 na inicialização.

  • Use o @reboot do cron para executar o comando após a inicialização.

    Adicionar ao (root) crontab:

    @reboot shutdown -P +60
    

Para os dois últimos métodos, você também pode usar sleep 3600 && shutdown -P now em vez de usar argumento de tempo para shutdown para atrasar o desligamento por 60 minutos. Desta forma logins são possíveis até o último momento antes de o desligamento ser emitido.

    
por 02.10.2018 / 12:19
35

Isso parece um problema XY .

My tasks take usually no more than 15 minutes. I would like to implement a mechanism to shutdown it automatically after 60 minutes.

Se você desligar após 60 minutos, corre o risco de estar com um problema particularmente complicado e precisar de mais tempo. Muitas das soluções anteriores não facilitariam o atraso do encerramento.

Se a tarefa não for uma tarefa interativa, mas sim uma tarefa com script que é automaticamente disparada de outra máquina, @sdkks forneceu uma ótima solução para isso; você realmente deve apenas fazer a máquina executar o poweroff assim que o script e todas as suas tarefas terminarem.

No entanto, se sua tarefa for interativa, sugerimos que você faça a detecção inativa.

Se você executar sua tarefa em uma GUI (X11), poderá detectar as sessões GUI inativas usando a abordagem descrita aqui: Executar um comando quando o sistema está ocioso e quando está ativo novamente

Se você fizer a tarefa através de um terminal, poderá detectar usuários logados usando o comando who . Você pode configurar um cronjob que desligue a máquina se who retornar um resultado vazio. Note que esta será uma abordagem bastante conservadora; ele não desligará o sistema se você deixar o console conectado, mas ocioso.

Se você quiser ser um pouco mais agressivo e desconectar também as sessões de terminal inativas, você pode combinar a abordagem anterior com desconectando automaticamente sessões SSH ociosas ClientAliveInterval e ClientAliveCountMax . Outra abordagem para isso, se você não tiver SSH, mas tiver uma sessão de terminal local, é usar o tempo de terminal ocioso conforme retornado pelo comando w .

    
por 02.10.2018 / 17:24
8

Embora todas as respostas anteriores satisfaçam o requisito de perfeição, você também pode desligar a sua máquina assim que as tarefas forem concluídas.

Os scripts

bash podem ser trap ped, o que significa que certos sinais podem ser interceptados e certas tarefas podem ser executadas quando necessário. EXIT é um dos sinais que podem ser capturados.

Você seria capaz de:

  1. Defina um trap para EXIT de seus scripts de shell automatizados, o que significa término de suas tarefas automatizadas
  2. Defina um trap para seu .bashrc EXIT , ou seja, sempre que você fizer logout dessa máquina, desligue-a.

A opção nº 1 seria o caso ideal, desde que suas tarefas não requeiram inspeção ad hoc e julgamento manual.

A opção nº 2 cobriria os casos em que você esqueceria de sair do terminal sem desligar. Há uma ressalva embora; se você tiver vários terminais para a mesma máquina abertos e você sair de um deles, ele ainda desligará a máquina da mesma forma. (Pode ser roteirizado para evitar isso, mas não vou complicar a solução.)

cleanup(){
    # Do some tasks before terminating
    echo oh la la, cleaning is so nice
    echo "See you later, world"
    sudo poweroff & # finally shutdown
}
trap cleanup EXIT

Isso pode ser no final de .bashrc para a opção nº 2, em algum lugar na parte superior do seu script para a opção nº 1.

Por que não usar poweroff no final do script?

Eu prefiro usar set -eo pipefail no topo dos meus scripts. Se algum erro acontecer, não falhará silenciosamente; Parará de executar mais comandos. O sinal trap de EXIT deve cobrir os casos em que o script termina prematuramente devido a erros.

No entanto, para as suas tarefas, isso também pode significar que a máquina será desligada antes de serem concluídas.

Eu tenho um modelo simples de bash que uso para facilitar a depuração de scripts; talvez possa ser de alguma utilidade. Por favor, veja esta essência .

    
por 02.10.2018 / 14:25
5

Elaborando o comentário @dirkt, você pode inserir um comando at no seu .bashrc ou .profile ou qualquer arquivo que seu shell use no login para agendar um desligamento automático 60 minutos após o seu login.

Algo como:

at now + 60 minutes -f /sbin/halt
    
por 02.10.2018 / 12:20
5

O seguinte executa command com os parâmetros e, se for concluído com êxito, desligará a caixa imediatamente, supondo que o usuário possa executar poweroff . Pode ser necessário usar sudo poweroff .

command --parameters && poweroff

Considerando que o seguinte simplesmente executa poweroff imediatamente quando o comando termina:

command --parameters ; poweroff

Se você acha que o comando precisa de tempo de descanso após a conclusão, execute

command --parameters ; sleep 3600 ; poweroff

Se você acha que o comando pode executar horas extras, você pode restringi-lo a uma hora:

timeout 1h command --parameters ; poweroff

timeout faz parte do pacote coreutils , então você provavelmente já o tem.

    
por 03.10.2018 / 03:57
3

Se você está realmente preocupado com a segurança, use um temporizador de saída mecânica na fonte de alimentação. Basta configurá-lo para qualquer hora que você quiser desligar. Desta forma, ninguém pode acessar remotamente e desativar o desligamento. Você precisaria de acesso físico.

    
por 02.10.2018 / 19:14
2

Se você estiver em uma máquina systemd , poderá usar um timer monotônico

A unidade do temporizador /etc/systemd/system/shutdown_after_an_hour.timer

[Unit]
Description=shutdown after an hour

[Timer]
OnBootSec=1h

[Install]
WantedBy=timers.target

A unidade do temporizador /etc/systemd/system/shutdown_after_an_hour.service :

[Unit]
Description=shutdown after an hour

[Service]
ExecStart=/sbin/poweroff --force --no-wall
Type=oneshot

Está ativado via

# systemctl enable shutdown_after_an_hour.timer

Seu status (principalmente quanto tempo resta antes do desligamento) está disponível via

# systemctl list-timers shutdown_after_an_hour.timer

Ele funcionará na próxima reinicialização, não é útil para systemctl start durante a sessão quando ele é criado, pois ele não funcionará (porque não foi acionado durante a reinicialização) ou desligará a máquina imediatamente se passado uma hora. Eu não sei qual vai acontecer, eu nunca testei esse caso específico.

    
por 04.10.2018 / 12:37
1

Tente colocar o script ( sudo shutdown -P 3600 ) no diretório /etc/init.d para executá-lo automaticamente na inicialização.

Ou tente usar anacron , adicionando o comando no arquivo /etc/anacrontab . Eu também sugiro usar nohup na frente do comando para ter certeza de que o comando ainda está funcionando após o logout.

    
por 02.10.2018 / 12:46
0

Aproveite o arquivo de logout do seu Shell

Se você precisar apenas do servidor para tarefas interativas ou não interativas iniciadas pelo seu UID, considere colocar seus comandos de desligamento no arquivo ~ / .bash_logout . O Manual do GNU Bash diz:

When an interactive login shell exits, or a non-interactive login shell executes the exit builtin command, Bash reads and executes commands from the file ~/.bash_logout, if it exists.

Portanto, adicionar "sudo poweroff" ou semelhante ao seu arquivo de logoff é desligar o servidor assim que você efetua logout de sua sessão atual ou quando uma sessão Bash não interativa chama exit . Você também pode escolher usar at ou passar um tempo para desligar se preferir adiar o desligamento.

Para uma abordagem mais interativa, você pode colocar os seguintes Bashisms em seu arquivo de logout:

# Shutdown unless N or n is pressed within 30 seconds.
shopt -s nocasematch
read -t 30 -N 1 -p 'Shutdown now? (Y/n) '
[[ "$REPLY" =~ n ]] || sudo poweroff

Advertências

Existem algumas advertências que você deve ter em mente sobre essa solução:

  • Isso provavelmente funcionará mesmo sob um terminal iniciado pelo X Windows, mas provavelmente não funcionaria para uma sessão X11 que não foi lançada por startx ou similar.
  • Se você tiver scripts não interativos que chamam exit , talvez haja desligamentos que não está esperando.
  • Seu arquivo sudoers pode solicitar uma senha se você não tiver especificado NOPASSWD para os comandos de desligamento ou se você não tiver chamado sudo -v antes de executar o comando de desligamento.
  • Provavelmente existem outros casos de limites nos quais ainda não pensei.
Em suma, você pode querer considerar se essa abordagem atende à sua necessidade real ou se uma abordagem completamente diferente, como monitorar a ausência de usuários registrados ou alguma outra alternativa, é uma aposta melhor. Sua milhagem definitivamente variará.

    
por 04.10.2018 / 17:19

Tags