Debian - como executar um script na inicialização assim que houver uma conexão à Internet pronta para uso?

14

Estou executando o Debian 7 Wheezy e preciso iniciar algumas telas na inicialização assim que houver uma conexão com a Internet totalmente funcional. No entanto, não, se a conexão à Internet quebrou e foi conectada novamente. Portanto, apenas na primeira conexão de internet funcional após a inicialização.

Você poderia, por favor, postar um script fictício para isso e me dizer onde colocá-lo e fazê-lo ser executado sob as condições especificadas?

O script só precisa iniciar a tela e terminar, mas a tela deve continuar.


EDITAR Já ouvi falar da /etc/network/if-up.d/pasta. Mas como posso garantir que o script não seja executado novamente se a conexão com a Internet for perdida e depois restabelecida?

MinecraftShamrock
fonte
@Celada por favor veja a edição
MinecraftShamrock

Respostas:

21

Coloque seu script /etc/network/if-up.de torne-o executável. Ele será executado automaticamente sempre que surgir uma interface de rede.

Para fazê-lo funcionar apenas na primeira vez em que é executado em cada inicialização, verifique se existe um arquivo de sinalizador criado após a primeira vez. Exemplo:

#!/bin/sh

FLAGFILE=/var/run/work-was-already-done

case "$IFACE" in
    lo)
        # The loopback interface does not count.
        # only run when some other interface comes up
        exit 0
        ;;
    *)
        ;;
esac

if [ -e $FLAGFILE ]; then
    exit 0
else
    touch $FLAGFILE
fi

: here, do the real work.
Celada
fonte
O arquivo de flag será excluído quando o servidor for desligado?
precisa
1
Sim, porque no Debian /var/runexiste um sistema de arquivos volátil (a tmpfs). Portanto, é garantido que ele fique vazio a cada inicialização.
Celada
1
Boa pegada. Eu acho que você teria que ser realmente azarado, mas acho que sim, por causa das interfaces hot-plugged que poderiam ser criadas simultaneamente. Então, eu acho que você pode fazer isso atomicamente em vez de testar e criar, o que tornaria seguro, mas o que eu vim da cabeça não é bonito! python -c 'import os; os.open("/var/run/work-was-already-done", os.O_EXCL|os.O_CREAT, 0)' 2>/dev/null || exit 0
Celada
3
@MinecraftShamrock Se você usar o script do Celada como está, seu código será executado assim que a interface de loopback aparecer. Se você quiser esperar pela conectividade com a Internet, pelo menos verifique IFACEse não é lo- ou alguma interface virtual - ou melhor, teste a conectividade com a Internet executando o ping.
Gilles 'SO- stop be evil'
1
O @MinecraftShamrock $IFACEpode ter como valores qualquer interface que surgir. Você pode listar todas as interfaces existentes ip linkou verificar quais delas estão configuradas para serem ativadas pela varredura/etc/network/interfaces
Celada
9

Este é um trabalho muito adequado systemd.

Executando um script como um serviço systemd

Se o seu sistema estiver executando o systemd , você poderá configurar seu script para ser executado como um serviço systemd que fornece controle sobre o ciclo de vida e o ambiente de execução, além de pré-condições para iniciar o script, como a rede em funcionamento.

A pasta recomendada para seus próprios serviços é /etc/systemd/system/(outra opção é/lib/systemd/system mas que normalmente deve ser usada apenas para serviços OOTB).

Crie o arquivo, por exemplo, com sudo vim /etc/systemd/system/autossh.service:

[Unit]
# By default 'simple' is used, see also https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
# Type=simple|forking|oneshot|dbus|notify|idle
Description=Autossh keepalive daemon
## make sure we only start the service after network is up
Wants=network-online.target
After=network.target

[Service]
## here we can set custom environment variables
Environment=AUTOSSH_GATETIME=0
Environment=AUTOSSH_PORT=0
ExecStart=/usr/local/bin/ssh-keep-alive.sh
ExecStop=pkill -9 autossh
# don't use 'nobody' if your script needs to access user files
# (if User is not set the service will run as root)
#User=nobody

# Useful during debugging; remove it once the service is working
StandardOutput=console

[Install]
WantedBy=multi-user.target

Agora você pode testar o serviço:

sudo systemctl start autossh

Verificando o status do serviço:

systemctl status autossh

Parando o serviço:

sudo systemctl stop autossh

Depois de verificar se o serviço funciona conforme o esperado, ative-o com:

sudo systemctl enable autossh

NOTA: Por questões de segurança, systemdo script será executado em um ambiente restrito, semelhante à maneira como os crontabscripts são executados, portanto, não faça suposições sobre variáveis ​​de sistema preexistentes, como $ PATH. Use as Environmentchaves se seu script precisar de variáveis ​​específicas a serem definidas. Adicionar set -xna parte superior do script bash e depois executar systemctl status my_servicepode ajudar a identificar por que o script está falhando. Como regra geral, sempre use caminhos absolutos para tudo echo, inclusive , ou defina explicitamente seu $ PATH adicionando Environment=MYVAR=abc.

ccpizza
fonte
2

A conexão à Internet é iniciada por uma entrada /etc/rc6.d/provavelmente S35networking. Se você alterar esse arquivo e inserir seus comandos no final, ou melhor, adicione um /etc/init.d/mystuffe vincule-o /etc/rc0.d/S36mystuffa ele e insira seus comandos, então isso será iniciado assim que a rede estiver ativa.

Anthon
fonte
Será chamado se a conexão for perdida e depois restabelecida? Porque senão eu poderia apenas colocar o script em/etc/network/if-up.d
MinecraftShamrock
Não, isso é apenas na inicialização
Anthon 6/14
1
Isso funcionará, mas, para fins de correção, deixe-me salientar que nenhum script /etc/rc0.dserá executado na inicialização, eles serão executados no desligamento (nível 0). Na inicialização, seria algo /etc/rc2.dparecido ou semelhante. Especificamente para o Debian chiado do OP, é /etc/rcS.d/S12networking. Tudo simboliza o mesmo arquivo, é claro. BTW @Anthon também obrigado por corrigir minha resposta: "Please" em vez de "Put"? Que erro de digitação estranho!
Celada
@ Celada Você tem o direito rc6 no meu (sistema não-Debian). Eu não tinha certeza se você queria 'Por favor, coloque' lá, mas apenas "Put" parecia mais crocante. BTW eu votei na sua resposta, é apenas uma abordagem melhor para redes, pois tem isso if-up.dcomo mecanismo genérico que também funciona em uma reconexão.
Anthon