Como executar um script de shell na inicialização

367

Em uma instância do Amazon S3 Linux, tenho dois scripts chamados start_my_appe stop_my_appque iniciam e param para sempre (que, por sua vez, executa meu aplicativo Node.js.). Eu uso esses scripts para iniciar e parar manualmente meu aplicativo Node.js. Por enquanto, tudo bem.

Meu problema: também quero configurá-lo para que start_my_appseja executado sempre que o sistema inicializar. Sei que preciso adicionar um arquivo init.de sei como vinculá-lo ao diretório apropriado rc.d, mas não consigo descobrir o que realmente precisa ser inserido no arquivo em que coloco init.d. Estou pensando que deveria ser apenas uma linha, tipo start_my_app, mas que não tem funcionado para mim.

meetamit
fonte
5
Não sou especialista nesse tipo de coisa, mas acho que a init.dsolução ( aqui ) deve ser preferida à rc.localsolução, porque a última é a ferramenta antiga que ainda é utilizável apenas porque a nova ferramenta é compatível com versões anteriores.
erikbwork
pm2 inicia meu_app; inicialização pm2; pm2 save github.com/Unitech/pm2
Unitech

Respostas:

292

No arquivo que você colocou, /etc/init.d/você deve configurá-lo como executável:

chmod +x /etc/init.d/start_my_app

Graças a @meetamit, se isso não funcionar, você deverá criar um link simbólico para /etc/rc.d/

ln -s /etc/init.d/start_my_app /etc/rc.d/

Observe que no Debian mais recente, isso não funcionará, pois seu script deve ser compatível com LSB (forneça, pelo menos, as seguintes ações: iniciar, parar, reiniciar, forçar recarregar e status): https: //wiki.debian .org / LSBInitScripts

Como uma observação, você deve colocar o caminho absoluto do seu script em vez de um relativo, pois ele resolve problemas inesperados:

/var/myscripts/start_my_app

E não se esqueça de adicionar em cima desse arquivo:

#!/bin/sh
Jonathan Muller
fonte
6
eu fiz isso e não funcionou. ele será executado automaticamente apenas porque está em /etc/init.d ou preciso fazer algo no topo para agendá-lo para ser executado quando o sistema iniciar?
Anfphient
4
@amphibient Não é bem o suficiente ... Você também precisa criar um link simbólico para o arquivo (usando lncomando) para um diretório dentrorc.d
meetamit
23
não há diretório rc.d na pasta etc da minha raiz. isso me deixou perplexo, não é um diretório crucial que o Linux precisa iniciar? Está faltando apenas um sistema operacional no meu sistema operacional parece funcionar bem. Eu tenho que criá-lo? Vejo um monte de arquivos com nomes semelhantes, como "rc1.d", até "rc5.d".
OKGimmeMoney
3
Não tenho nenhuma /etc/rc.dpasta, mas tenho /etc/rcX.dpastas (ou seja , /etc/rc0.d , /etc/rc1.d , /etc/rcS.d ), também há um arquivo /etc/rc.local . Eu acho que você deve criar links simbólicos em pasta personalizada como /etc/rc9.dou em um dos existentes ... (Servidor Ubuntu 14.04)
F8ER
2
Esta pergunta me ajudou com isso: unix.stackexchange.com/questions/28679/…
seth10 23/17
344

Defina um crontab para isso

#crontab -e
@reboot  /home/user/test.sh

após cada inicialização, ele executa o script de teste.

Hemant kumar
fonte
4
Esta é a única solução que funcionou para mim sem complicações! obrigado
whoopididoo
20
Esta é a melhor solução, @reboot sh $HOME/test.shno crontab é ainda mais limpo #
user3667089
4
@ user3667089 na verdade, não está funcionando. Abro o terminal, insiro "crontab -e", uma janela aparece, onde escrevo em "@reboot sh /home/user/test.sh", mas ele não roda na inicialização. Onde estou fazendo errado?
MycrofD
11
@ user3667089 as linhas padrão habituais '# Edite este arquivo para ...' e depois a linha que escrevi '@reboot sh /home/.../.sh'. Eu também tentei '@reboot /home/.../.sh' sem o "sh" inicial, mas sem resultados.
MycrofD
3
@ MycrofD o seu crontab -ldeve mostrar @reboot sh $HOME/test.shpara confirmar que ele realmente foi definido.
user3667089
124

Uma abordagem simples é adicionar uma linha em /etc/rc.local:

/PATH/TO/MY_APP &

ou se você deseja executar o comando como um usuário especial:

su - USER_FOOBAR -c /PATH/TO/MY_APP &

(o e comercial final embasa o processo e permite que o rc.local continue executando)

Se você deseja um script init completo, a distribuição debian tem um arquivo de modelo, então:

cp /etc/init.d/skeleton /etc/init.d/your_app

e adapte um pouco.

Gilles Quenot
fonte
2
Obrigado! Essa abordagem funcionou melhor, considerando os requisitos simples. Tenho certeza de que preciso especificar o usuário; caso contrário, quando precisar interromper o aplicativo manualmente (executando stop_my_app), eu precisaria fazê-lo sudo, não? Além disso, estou me perguntando qual é exatamente a função do e comercial final (?).
Meetamit 19/10/12
3
O usuário depende do seu aplicativo. Mas se não for absolutamente necessário para rodar como root, evite-o. &execute o processo em segundo plano
Gilles Quenot
2
sputnick, desculpe, mas eu tenho que marcar a resposta de Koren como a resposta aceita, principalmente por causa do que o @ erikb85 apontou, mas também porque minha pergunta original pediu a init.dmaneira de fazer as coisas (sua resposta era apenas uma solução mais simples para mim na época) . Esta postagem recebe muitas visualizações e votos, por isso é importante manter a precisão.
Meetamit
4
Não parece ser mencionado que o e comercial final embasa o processo e permite que o rc.local continue executando.
Mchicago
Obrigado por isso! Passe as últimas horas batendo minha cabeça contra a parede enquanto eu estava tentando fazer um serviço, mas nada funcionou. Tentei isso, funciona como um encanto!
Marko Grešak
35

É assim que eu faço no Red Hat Linux sistemas .

Coloque seu script /etc/init.d, de propriedade de raiz e executável. Na parte superior do script, você pode fornecer uma diretiva parachkconfig . Exemplo, o script a seguir é usado para iniciar um aplicativo Java como usuário oracle.

O nome do script é /etc/init.d/apex

#!/bin/bash
# chkconfig: 345 99 10
# Description: auto start apex listener
#
case "$1" in
 'start')
   su - oracle -c "cd /opt/apex ; java -jar apex.war > logs/apex.log 2>logs/apex_error.log &";;
 'stop')
   echo "put something to shutdown or kill the process here";;
esac

Isso indica que o script deve ser executado nos níveis 3, 4 e 5, e a prioridade para iniciar / parar é 99 e 10.

Em seguida, como usuário, rootvocê pode usar chkconfigpara ativar ou desativar o script na inicialização:

chkconfig --list apex
chkconfig --add apex

E você pode usar service start/stop apex.

Saule
fonte
Enquanto isso, experimentei um pacote chamado supervisord ( supervisord.org ), disponível no repositório epel. Pode ser usado para iniciar programas e monitorá-los, reiniciando-os com falha.
Saule
Em vez de digitar: "chkconfig --add service_name" depois de colocar script para /etc/init.d/ pasta pode escrever: "service_name chkconfig on"
Dragan Radevic
23

Entre cronusando sudo:

sudo crontab -e

Adicione um comando para executar na inicialização, neste caso, um script:

@reboot sh /home/user/test.sh

Salve :

Pressione ESC então: x para salvar e sair ou pressione ESC e ZZ (que é shift + zz)

Teste Teste Teste :

  1. Execute seu script de teste sem cron para garantir que ele realmente funcione.

  2. Certifique-se de salvar seu comando no cron, use sudo crontab -e

  3. Reinicie o servidor para confirmar que tudo funciona sudo @reboot

user3140639
fonte
Gosto muito disto. Obrigado! Ps. não use sudose você deseja executar um determinado comando durante a inicialização usando o usuário atual.
danger89
Onde essas informações devem ser armazenadas? Não está /tmp??
Peter Mortensen
15

Basta adicionar uma linha ao seu crontab.

Verifique se o arquivo é executável:

chmod +x /path_to_you_file/your_file

Para editar o arquivo crontab:

crontab -e

Linha que você precisa adicionar:

@reboot  /path_to_you_file/your_file

Que simples!

Luciano Ghilarducci
fonte
Isso não funciona para mim, está faltando alguma coisa? # uname -a Linux accton-xp70a0-26-a1 3.11.10-301.fc20.x86_64 #1 SMP Thu Dec 5 14:01:17 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
Isso funcionou para mim no CentOs 7. Para aqueles com problemas, eu precisava criar um shell script, torná-lo executável (chmod + x file_name) e chamar o shell script do cron, que por sua vez chama o nó path_to_file / index.js
SeanOlson
11

Outra opção é ter um comando @reboot no seu crontab.

Nem todas as versões do cron suportam isso, mas se sua instância for baseada na Amazon Linux AMI, ela funcionará.

chris
fonte
6

Você consegue :

chmod +x PATH_TO_YOUR_SCRIPT/start_my_app 

então use este comando

update-rc.d start_my_app defaults 100

Por favor, veja esta página na Cyberciti .

IR PRO
fonte
11
Eu tenho uma configuração básica, construída no yocto e essa foi a única maneira de fazer meu script funcionar. Obrigado.
Catalin Vasile
3

Crie seu próprio / init executável

Não é isso que você quer, mas é divertido!

Basta escolher um arquivo executável arbitrário, mesmo um script de shell , e inicializar o kernel com o parâmetro de linha de comando:

init=/path/to/myinit

No final da inicialização, o kernel do Linux executa o primeiro espaço de usuário executável no caminho especificado.

Vários projetos fornecem serviços populares init executáveis usados ​​pelas principais distribuições, por exemplo, systemd, e na maioria das distribuições o init bifurca um monte de processos usados ​​na operação normal do sistema.

Mas podemos sequestrar /init lo para executar nossos próprios scripts mínimos para entender melhor nosso sistema.

Aqui está uma configuração mínima reproduzível: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/f96d4d55c9caa7c0862991025e1291c48c33e3d9/README.md#custom-init

Ciro Santilli adicionou uma nova foto
fonte
2

Essa solução simples funcionou para mim em uma instância do Amazon Linux executando o CentOS. Edite seu /etc/rc.d/rc.localarquivo e coloque o comando lá. É mencionado neste arquivo que será executado após todos os outros scripts de inicialização. Portanto, tenha cuidado a esse respeito. É assim que o arquivo está para mim atualmente. insira a descrição da imagem aqui. Última linha é o nome do meu script.

shshnk
fonte
1

O método mais fácil absoluto, se tudo o que você deseja executar é um script simples (ou qualquer outra coisa), é se você tiver uma interface gráfica para usar as preferências do sistema e os aplicativos de inicialização.

basta procurar o script que você deseja e pronto. (torne o script executável)

varredor de campo
fonte
3
Na verdade, isso não é executado na inicialização, mas no login, o que é uma grande diferença. Também depende de uma determinada configuração, pois você não terá "Sistema> Preferências" em todos os sistemas (especialmente servidores).
jazzpi
o termo de pesquisa 'linux execute at startup' me levou a essa resposta, pela qual eu estava procurando. Mesmo que não responda à pergunta do OP, isso pode ajudar noobs do linux (ubuntu) como eu, por isso merece um voto positivo. Também não gosto, mas isso é pragmatismo.
thymaro
1

Para o Debian 9, consulte /ubuntu/228304/how-do-i-run-a-script-at-start-up . Isso me ajudou. Versão curta para o Debian 9: adicione comandos (como root) ao /etc/rc.local

/path_to_file/filename.sh ||  exit 1   # Added by me
exit 0

Provavelmente, /path_to_file/filename.sh deve ser executável (acho que sim).

Mikhail Ionkin
fonte
1

No Lubuntu, tive que lidar com a situação oposta. O Skype começa a funcionar após a inicialização e eu encontrei no ~/.config/autostart/arquivo skypeforlinux.desktop. O conteúdo do arquivo é o seguinte:

[Desktop Entry]
Name=Skype for Linux
Comment=Skype Internet Telephony
Exec=/usr/bin/skypeforlinux
Icon=skypeforlinux
Terminal=false
Type=Application
StartupNotify=false
X-GNOME-Autostart-enabled=true

A exclusão deste arquivo me ajudou.

aerijman
fonte
0
  • Adicione seu script ao diretório /etc/init.d/
  • Atualize seus níveis de execução rc: em $ update-rc.d myScript.sh defaults NNque NN é a ordem em que deve ser executado. 99, por exemplo, significa que seria executado após 98 e antes de 100.
Kibrom Gebre
fonte
0

Trabalhando com microsserviços ou shell do Python 3; usando o Ubuntu Server 18.04 (Bionic Beaver) ou Ubuntu 19.10 (Eoan Ermine) ou Ubuntu 18.10 (Cosmic Cuttlefish), eu sempre gosto dessas etapas e funcionou sempre :

  1. Criando um microsserviço chamado p exemplo "brain_microservice1.service" no meu caso:

    $ nano /lib/systemd/system/brain_microservice1.service
  2. Dentro deste novo serviço em que você está:

    [Unit]
    Description=brain_microservice_1
    After=multi-user.target
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/python3.7 /root/scriptsPython/RUN_SERVICES/microservices    /microservice_1.py -k start -DFOREGROUND
    ExecStop=/usr/bin/python3.7 /root/scriptsPython/RUN_SERVICES/microservices/microservice_1.py -k graceful-stop
    ExecReload=/usr/bin/python3.7 /root/scriptsPython/RUN_SERVICES/microservices/microservice_1.py -k graceful
    PrivateTmp=true
    LimitNOFILE=infinity
    KillMode=mixed
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target
  3. Dê as permissões:

    $ chmod -X /lib/systemd/system/brain_microservice*
    $ chmod -R 775 /lib/systemd/system/brain_microservice*
  4. Conceda a permissão de execução:

    $ systemctl daemon-reload
  5. Habilite então, isso fará com que sempre inicie na inicialização

    $ systemctl enable brain_microservice1.service
  6. Então você pode testá-lo;

    $ sudo reinicie agora

  7. Concluir = SUCESSO !!

Isso pode ser feito com o mesmo script do corpo para executar o shell, reagir ... script de inicialização do banco de dados ... qualquer tipo de código OS ... espero que isso ajude ...

...

Renan Moura
fonte
0

Aqui está um método mais simples!

Primeiro: escreva um shell script e salve-o como .sh, aqui está um exemplo

#!/bin/bash
Icoff='/home/akbar/keyboardONOFF/icon/Dt6hQ.png'
id=13
fconfig=".keyboard"
echo "disabled" > $fconfig
xinput float $id
notify-send -i $Icoff "Internal Keyboard disabled";

esse script desativará o teclado interno na inicialização.

Segundo: abra o aplicativo "Preferências do aplicativo de inicialização"

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Terceiro: clique em Adicionar. quarto: na seção NAME, dê um nome. quinto: Na seção de comando, navegue até o seu .sh. sexta: edite sua seção de comando para:

bash <space> path/to/file/<filename>.sh <space> --start

sétimo: clique em Adicionar. É isso aí! Acabado!

Agora confirme reiniciando o seu PC.

Felicidades!

akbar ali
fonte
-1

O método indolor, mais fácil e mais universal é simplesmente executá-lo com ~.bash_profileou ~.profile (se você não tiver o arquivo bash_profile) .

Basta adicionar o comando de execução na parte inferior desse arquivo e ele será executado quando o sistema for iniciado.

Eu tenho este na parte inferior um exemplo; ~\Desktop\sound_fixer.sh

Juko
fonte
2
Isso é impreciso. ~/.bash_profileexecuta quando o usuário efetua login - não quando o sistema é inicializado. Na pergunta original, a intenção é executar um servidor de aplicativos Node.js. na inicialização da máquina. Sua solução exigiria que um usuário humano fizesse primeiro login na máquina antes da execução do servidor Node.js. E, se algum tipo de problema faz com que uma reinicialização do servidor durante a noite, o aplicativo nunca mais voltar à vida até que os registros humanos de volta.
meetamit
-6

Para algumas pessoas, isso funcionará:

Você pode simplesmente adicionar o seguinte comando em SistemaPreferênciasAplicativos de Inicialização :

bash /full/path/to/your/script.sh
SagarSave
fonte
Não vejo isso no menu de preferências do sistema. Mas eu o vejo quando procuro no iniciador de aplicativos.
OKGimmeMoney
Na verdade, isso não é executado na inicialização, mas no login, o que é uma grande diferença. Também depende de uma determinada configuração, pois você não terá "Sistema> Preferências" em todos os sistemas (especialmente servidores).
jazzpi
3
Essa resposta parece mais para a área de trabalho do Ubuntu / Linux, mas o usuário está realmente solicitando ajuda para uma instância do AWS EC2 Linux, que, até onde eu saiba, não possui GUI.
Vini.g.fer