Tenho um servidor que normalmente está desligado por questões de segurança. Quando quero trabalhar nele, ligo-o, executo minhas tarefas e o desligo novamente. Minhas tarefas geralmente não levam mais de 15 minutos. 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. Eu só posso definir padrões periódicos, mas eles não levam esses dados em consideração.
Como eu poderia fazer essa implementação?
Existem várias opções.
Fornecer tempo diretamente para
shutdown -P
:Observe que a
shutdown
página man também aponta:Use
at
o comando.Crie um arquivo de unidade systemd ou script de inicialização que seja executado
shutdown -P 60
na inicialização.Use o cron
@reboot
para executar o comando após a inicialização.Adicionar ao crontab (raiz):
Para os dois últimos métodos, você também pode usar
sleep 3600 && shutdown -P now
em vez de usar o argumento timeshutdown
para atrasar o desligamento por 60 minutos. Dessa forma, os logins são possíveis até o último momento antes do desligamento.Isso parece um problema XY .
Se você desligar após 60 minutos, corre o risco de estar com um problema particularmente complicado e só precisar de mais tempo. Muitas das soluções anteriores não facilitariam o atraso do desligamento.
Se a tarefa não for uma tarefa interativa, mas sim uma tarefa com script que é acionada automaticamente de outra máquina, @sdkks deu uma ótima solução para isso; você realmente deve apenas encarregar a máquina de executar o desligamento assim que o script e todas as suas tarefas terminarem.
No entanto, se sua tarefa for interativa, sugiro fazer a detecção de inatividade.
Se você fizer sua tarefa em uma GUI (X11), poderá detectar as sessões de GUI ociosas usando a abordagem descrita aqui: Execute um comando quando o sistema estiver ocioso e quando estiver ativo novamente
Se você fizer a tarefa por meio de um terminal, poderá detectar usuários logados usando o
who
comando. Você pode configurar um cronjob que desliga a máquina sewho
retornar um resultado vazio. Observe 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 ociosas, poderá combinar a abordagem anterior com a desconexão automática de sessões SSH ociosas
ClientAliveInterval
eClientAliveCountMax
. Outra abordagem para isso, se você não tiver SSH, mas tiver uma sessão de terminal local, é usar o tempo ocioso do terminal conforme retornado pelow
comando.Se você executar suas tarefas como o mesmo usuário todas as vezes, basta 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.
Adicionado:
Depois de ler a maioria das outras respostas, adoro a opção de adicionar "@reboot /<path to script/command>" no cron (raiz). Resposta dada por sebasth como sua quarta opção. Você pode adicionar o comando shutdown ou escrever um pequeno script que execute o shutdown e execute-o via cron. O WoJ também tem uma ótima solução se você usar o systemd.
Embora as respostas anteriores aqui satisfaçam o requisito com perfeição, você também pode desligar sua máquina assim que as tarefas forem concluídas.
bash
scripts podem sertrap
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:
trap
forEXIT
de seus scripts de shell automatizados, significando o encerramento de suas tarefas automatizadastrap
para o seu.bashrc
EXIT
, ou seja, sempre que você sair dessa máquina, desligue-a.A opção nº 1 seria o caso ideal, desde que suas tarefas não exijam 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; se você tiver vários terminais para a mesma máquina abertos e 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.)
Isso pode estar no final da
.bashrc
opção #2, em algum lugar no topo do seu script para a opção #1.Por que não usar
poweroff
no final do script?Eu prefiro usar
set -eo pipefail
at no topo dos meus scripts. Se ocorrer algum erro, ele não falhará silenciosamente; ele irá parar de executar mais comandos.trap
deEXIT
sinal deve abranger os casos em que o script termina prematuramente devido a erros.No entanto, para suas tarefas, isso também pode significar que a máquina será desligada antes de serem concluídas.
Eu tenho um
bash
modelo simples que uso para facilitar a depuração de scripts; talvez possa ser de alguma utilidade. Por favor, veja esta essência .O seguinte é executado
command
com parâmetros e, se for concluído com êxito, desligará a caixa imediatamente, supondo que o usuário possa executarpoweroff
. Pode ser necessário usarsudo poweroff
.Enquanto o seguinte simplesmente é executado
poweroff
imediatamente quando o comando termina:Se você acha que o comando precisa de tempo de descanso após a conclusão, execute
Se você acha que o comando pode ser executado horas extras, pode restringi-lo a uma hora:
timeout
faz parte docoreutils
pacote, então você provavelmente já o tem.Elaborando o comentário @dirkt, você pode inserir um
at
comando no seu.bashrc
ou em.profile
qualquer arquivo que seu shell use no login para agendar um desligamento automático 60 minutos após o login.Algo como:
Se você estiver realmente preocupado com a segurança, use um temporizador de saída mecânico na fonte de alimentação. Basta configurá-lo para qualquer hora que você deseja desligar. Dessa forma, ninguém pode fazer login remotamente e desativar o desligamento. Você precisaria de acesso físico.
Tente colocar o script (
sudo shutdown -P 3600
) no/etc/init.d
diretório para executá-lo automaticamente na inicialização.Ou tente usar
anacron
, adicionando o comando no/etc/anacrontab
arquivo. Também sugiro usarnohup
na frente do comando para ter certeza de que o comando ainda está funcionando após o logout.Se você estiver em uma
systemd
máquina, você pode usar um timer monotônicoA unidade do temporizador
/etc/systemd/system/shutdown_after_an_hour.timer
A unidade do temporizador
/etc/systemd/system/shutdown_after_an_hour.service
:É habilitado através
Seu status (particularmente quanto tempo resta antes do desligamento) está disponível via
Ele funcionará na próxima reinicialização, não é útil
systemctl start
durante a sessão quando é criado, pois não funcionará (porque não foi acionado durante a reinicialização) ou desligará a máquina imediatamente se passar de uma hora. Não sei qual vai acontecer de fato, nunca testei esse caso específico.Aproveite o arquivo de logout do seu Shell
Se você precisar do servidor apenas para tarefas interativas ou não interativas iniciadas por seu UID, considere colocar seus comandos de desligamento em seu arquivo ~/.bash_logout . O Manual GNU Bash diz:
Portanto, adicionar "sudo poweroff" ou semelhante ao seu arquivo de logout desligaria o servidor assim que você sair da sua sessão atual ou quando uma sessão Bash não interativa chamar
exit
. Você também pode optar por usar em ou passar um atraso de tempo para o desligamento se preferir adiar o desligamento.Para uma abordagem mais interativa para isso, você pode colocar os seguintes Bashisms em seu arquivo de logout:
Ressalvas
Existem algumas advertências que você deve ter em mente sobre esta solução:
startx
ou similar.exit
, poderão ocorrer desligamentos inesperados.NOPASSWD
os comandos de desligamento ou se não tiver chamadosudo -v
antes de executar o comando de desligamento.Em resumo, 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 conectados ou alguma outra alternativa, é uma aposta melhor. Sua milhagem definitivamente vai variar.