Comment exécuter un script shell au démarrage

367

Sur une instance Amazon S3 Linux, j'ai deux scripts appelés start_my_appet stop_my_appqui démarrent et s'arrêtent pour toujours (qui à son tour exécute mon application Node.js). J'utilise ces scripts pour démarrer et arrêter manuellement mon application Node.js. Jusqu'ici tout va bien.

Mon problème: je veux également le configurer de sorte qu'il start_my_appsoit exécuté à chaque démarrage du système. Je sais que je dois ajouter un fichier à l'intérieur init.det je sais comment le lier au répertoire approprié à l'intérieur rc.d, mais je ne peux pas comprendre ce qui doit réellement aller à l'intérieur du fichier dans lequel je le place init.d. Je pense que ça devrait être juste une ligne, genre start_my_app, mais ça ne marche pas pour moi.

meetamit
la source
5
Je ne suis pas expérimenté dans ce genre de choses, mais je pense que la init.dsolution ( ici ) devrait être préférée à la rc.localsolution car cette dernière est l'ancien outillage qui n'est encore utilisable que parce que le nouvel outillage est rétrocompatible.
erikbwork
pm2 start my_app; démarrage pm2; pm2 save github.com/Unitech/pm2
Unitech

Réponses:

292

Dans le fichier que vous insérez, /etc/init.d/vous devez le définir comme exécutable avec:

chmod +x /etc/init.d/start_my_app

Merci à @meetamit, si cela ne fonctionne pas, vous devez créer un lien symbolique vers /etc/rc.d/

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

Veuillez noter que sur la dernière Debian, cela ne fonctionnera pas car votre script doit être conforme au LSB (fournissez, au moins, les actions suivantes: démarrer, arrêter, redémarrer, forcer le rechargement et l'état): https: //wiki.debian .org / LSBInitScripts

Remarque: vous devez mettre le chemin absolu de votre script au lieu d'un chemin relatif, cela peut résoudre des problèmes inattendus:

/var/myscripts/start_my_app

Et n'oubliez pas d'ajouter au dessus de ce fichier:

#!/bin/sh
Jonathan Muller
la source
6
j'ai fait ça et ça n'a pas fonctionné. fonctionnera-t-il automatiquement juste parce qu'il se trouve dans /etc/init.d ou dois-je faire quelque chose en plus pour le planifier pour qu'il s'exécute au démarrage du système?
amphibient
4
@amphibient Pas tout à fait suffisant ... Vous devez également créer un lien symbolique vers ce fichier (en utilisant la lncommande) vers un répertoire dansrc.d
meetamit
23
il n'y a pas de répertoire rc.d dans le dossier etc de ma racine. cela m'a stupéfait n'est-ce pas un répertoire crucial que Linux doit démarrer? Il manque juste un mon OS semble fonctionner correctement. Dois-je le créer? Je vois un tas de fichiers portant le même nom comme "rc1.d" jusqu'à "rc5.d"
OKGimmeMoney
3
Je n'ai pas de /etc/rc.ddossier, mais j'ai des /etc/rcX.ddossiers (Ie /etc/rc0.d , /etc/rc1.d , /etc/rcS.d ), il y a aussi un fichier /etc/rc.local . Je pense que vous devriez créer des liens symboliques dans un dossier personnalisé comme /etc/rc9.dou dans l'un des existants ... (Ubuntu Server 14.04)
F8ER
2
Cette question m'a aidé avec ceci: unix.stackexchange.com/questions/28679/…
seth10
344

Définissez un crontab pour cela

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

après chaque démarrage, il exécutera le script de test.

Hemant kumar
la source
4
C'est la seule solution qui a fonctionné pour moi sans tracas! merci
whoopididoo
20
Ceci est la meilleure solution, @reboot sh $HOME/test.shdans le crontab est encore plus propre
user3667089
4
@ user3667089 en fait, cela ne fonctionne pas. J'ouvre le terminal, saisis "crontab -e", une fenêtre apparaît, où j'écris dans "@reboot sh /home/user/test.sh" mais il ne s'exécute pas au démarrage. Où est-ce que je le fais mal?
MycrofD
1
@ user3667089 les lignes par défaut habituelles '# Modifier ce fichier en ...' puis la ligne que j'ai écrite '@reboot sh /home/.../.sh'. J'ai également essayé '@reboot /home/.../.sh' sans le "sh" initial mais sans résultat.
MycrofD
3
@MycrofD votre crontab -ldevrait apparaître @reboot sh $HOME/test.shpour confirmer qu'il a bien été défini.
user3667089
124

Une approche simple consiste à ajouter une ligne dans /etc/rc.local:

/PATH/TO/MY_APP &

ou si vous souhaitez exécuter la commande en tant qu'utilisateur spécial:

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

(l'esperluette arrière met en arrière plan le processus et permet au rc.local de continuer à s'exécuter)

Si vous voulez un script d'initialisation complet, la distribution debian a un fichier modèle, donc:

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

et l'adapter un peu.

Gilles Quenot
la source
2
Merci! Cette approche s'est avérée la plus efficace compte tenu des exigences simples. Je suis à peu près sûr que j'avais besoin de spécifier l'utilisateur, sinon lorsque stop_my_appje devrais arrêter manuellement l'application (en exécutant ), je devrais le faire avec sudo, non? De plus, je me demande quelle est exactement la fonction de l'esperluette arrière (?).
meetamit
3
L'utilisateur dépend de votre application. Mais s'il n'est pas absolument nécessaire de s'exécuter en tant que root, évitez-le. &exécuter le processus en arrière
Gilles Quenot
2
sputnick, désolé, mais je dois marquer Koren comme la réponse acceptée, principalement à cause de ce que @ erikb85 a souligné, mais aussi parce que ma question d'origine demandait la init.dfaçon de faire les choses (votre réponse était juste une solution de contournement plus simple pour moi à l'époque) . Ce message obtient beaucoup de vues et de votes, il est donc important de rester précis.
meetamit
4
Il ne semble pas être mentionné que l'esperluette arrière-plan met en arrière plan le processus et permet à rc.local de continuer à s'exécuter.
mchicago
Merci pour cela! J'ai passé quelques heures à me frapper la tête contre le mur pendant que j'essayais de faire un service, mais rien n'a fonctionné. J'ai essayé ça, ça marche comme un charme!
Marko Grešak
35

C'est ainsi que je le fais sur les systèmes Red Hat Linux .

Mettez votre script /etc/init.d, détenu par root et exécutable. En haut du script, vous pouvez donner une directive pour chkconfig. Par exemple, le script suivant est utilisé pour démarrer une application Java en tant qu'utilisateur oracle.

Le nom du script est /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

Cela signifie que le script doit s'exécuter aux niveaux 3, 4 et 5 et que la priorité de démarrage / arrêt est 99 et 10.

Ensuite, en tant qu'utilisateur, rootvous pouvez utiliser chkconfigpour activer ou désactiver le script au démarrage:

chkconfig --list apex
chkconfig --add apex

Et vous pouvez utiliser service start/stop apex.

Saule
la source
En attendant, j'ai expérimenté avec un paquet appelé supervisord ( supervisord.org ) qui est disponible dans le dépôt epel. Il peut être utilisé pour démarrer des programmes et les surveiller, en les redémarrant en cas d'échec.
Saule
Au lieu de taper: "chkconfig --add service_name" après avoir placé le script dans le dossier /etc/init.d/, vous pouvez taper: "chkconfig service_name on"
Dragan Radevic
23

Entrez en cronutilisant sudo:

sudo crontab -e

Ajoutez une commande à exécuter au démarrage, dans ce cas un script:

@reboot sh /home/user/test.sh

Sauver:

Appuyez sur ESC puis: x pour enregistrer et quitter, ou appuyez sur ESC puis sur ZZ (c'est-à-dire shift + zz)

Test Test Test :

  1. Exécutez votre script de test sans cron pour vous assurer qu'il fonctionne réellement.

  2. Assurez-vous d'avoir enregistré votre commande dans cron, utilisez sudo crontab -e

  3. Redémarrez le serveur pour confirmer que tout fonctionne sudo @reboot

user3140639
la source
J'aime beaucoup ça. Merci! Ps. ne pas utiliser sudosi vous souhaitez exécuter une certaine commande au démarrage en utilisant l'utilisateur actuel.
danger89
Où ces informations sont-elles censées être stockées? Pas dans /tmp??
Peter Mortensen
15

Ajoutez simplement une ligne à votre crontab ..

Assurez-vous que le fichier est exécutable:

chmod +x /path_to_you_file/your_file

Pour modifier le fichier crontab:

crontab -e

Ligne à ajouter:

@reboot  /path_to_you_file/your_file

C'est simple!

Luciano Ghilarducci
la source
Cela ne fonctionne pas pour moi, quelque chose me manque? # 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
Cela a fonctionné pour moi sur CentOs 7. Pour ceux qui ont des problèmes, j'avais besoin de créer un script shell, de le rendre exécutable (chmod + x nom_fichier) et d'appeler le script shell à partir du cron qui à son tour appelle le nœud path_to_file / index.js
SeanOlson
11

Une autre option consiste à avoir une commande @reboot dans votre crontab.

Toutes les versions de cron ne le prennent pas en charge, mais si votre instance est basée sur l'AMI Amazon Linux, cela fonctionnera.

chris
la source
6

Tu peux le faire :

chmod +x PATH_TO_YOUR_SCRIPT/start_my_app 

puis utilisez cette commande

update-rc.d start_my_app defaults 100

Veuillez consulter cette page sur Cyberciti .

IR PRO
la source
1
J'ai une configuration assez simple, construite sur yocto et c'était la seule façon de faire fonctionner mon truc de script. Merci.
Catalin Vasile
3

Créez votre propre exécutable / init

Ce n'est pas ce que vous voulez, mais c'est amusant!

Choisissez simplement un fichier exécutable arbitraire, même un script shell , et démarrez le noyau avec le paramètre de ligne de commande:

init=/path/to/myinit

Vers la fin du démarrage, le noyau Linux exécute le premier exécutable de l'espace utilisateur au chemin donné.

Plusieurs projets fournissent des initexécutables populaires utilisés par les principales distributions, par exemple systemd, et dans la plupart des distributions, init lancera un tas de processus utilisés dans le fonctionnement normal du système.

Mais nous pouvons le détourner /initpour exécuter nos propres scripts minimaux afin de mieux comprendre notre système.

Voici une configuration reproductible minimale: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/f96d4d55c9caa7c0862991025e1291c48c33e3d9/README.md#custom-init

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
2

Cette solution simple a fonctionné pour moi sur une instance Amazon Linux exécutant CentOS. Modifiez votre /etc/rc.d/rc.localfichier et placez-y la commande. Il est mentionné dans ce fichier qu'il sera exécuté après tous les autres scripts d'initialisation. Soyez donc prudent à cet égard. Voici à quoi ressemble le fichier pour moi actuellement. entrez la description de l'image ici. La dernière ligne est le nom de mon script.

shshnk
la source
1

La méthode la plus simple absolue si tout ce que vous voulez exécuter est un simple script, (ou quoi que ce soit), si vous avez un GUI pour utiliser le système> les préférences puis les applications de démarrage.

recherchez simplement le script que vous voulez et c'est parti. (rendre le script exécutable)

balayeuse
la source
3
Cela ne fonctionne pas réellement au démarrage, mais à la connexion, ce qui est une très grande différence. Cela dépend également d'une certaine configuration, car vous n'aurez pas "Système> Préférences" sur chaque système (en particulier les serveurs).
jazzpi
le terme de recherche «Linux exécuter au démarrage» m'a conduit à cette réponse, que je cherchais. Même s'il ne répond pas à la question par OP, cela pourrait aider les noobs linux (ubuntu) comme moi, donc il mérite un vote positif. Je n'aime pas ça non plus, mais c'est du pragmatisme.
thymaro
1

Pour Debian 9, voir /ubuntu/228304/how-do-i-run-a-script-at-start-up . Cela m'a aidé. Version courte pour Debian 9: ajoutez des commandes (en tant que root) à /etc/rc.local

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

Probablement, /path_to_file/filename.sh devrait être exécutable (je pense que oui).

Mikhail Ionkin
la source
1

À Lubuntu, j'ai dû faire face à la situation inverse. Skype commence à fonctionner après le démarrage et je l'ai trouvé dans ~/.config/autostart/le fichier skypeforlinux.desktop. Le contenu du fichier est le suivant:

[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

La suppression de ce fichier m'a aidé.

aerijman
la source
0
  • Ajoutez votre script au répertoire /etc/init.d/
  • Mettez à jour vos niveaux d'exécution rc: $ update-rc.d myScript.sh defaults NNoù NN est l'ordre dans lequel il doit être exécuté. 99, par exemple, signifie qu'il sera exécuté après 98 et avant 100.
Kibrom Gebre
la source
0

Travailler avec des microservices ou shell Python 3; en utilisant Ubuntu Server 18.04 (Bionic Beaver) ou Ubuntu 19.10 (Eoan Ermine) ou Ubuntu 18.10 (Cosmic Cuttlefish), j'aime toujours ces étapes, et cela a toujours fonctionné aussi:

  1. Création d'un microservice appelé p exemple "brain_microservice1.service" dans mon cas:

    $ nano /lib/systemd/system/brain_microservice1.service
  2. Au sein de ce nouveau service dans lequel vous vous trouvez:

    [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. Donnez les autorisations:

    $ chmod -X /lib/systemd/system/brain_microservice*
    $ chmod -R 775 /lib/systemd/system/brain_microservice*
  4. Donnez ensuite l'autorisation d'exécution:

    $ systemctl daemon-reload
  5. Activez ensuite, cela fera alors toujours démarrer au démarrage

    $ systemctl enable brain_microservice1.service
  6. Ensuite, vous pouvez le tester;

    $ sudo reboot now

  7. Terminer = SUCCÈS !!

Cela peut être fait avec le même script de corps pour exécuter le shell, réagir ... le script de démarrage de la base de données ... tout type de code os ... espérons que cette aide vous ...

...

Renan Moura
la source
0

Voici une méthode plus simple!

Tout d'abord: écrivez un script shell et enregistrez-le au format .sh voici un exemple

#!/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";

ce script désactivera le clavier interne au démarrage.

Deuxièmement: Ouvrez l'application "Préférences d'application de démarrage"

entrez la description de l'image ici

entrez la description de l'image ici

Troisièmement: cliquez sur Ajouter. quatrième: dans la section NOM, donnez un nom. cinquième: dans la section des commandes, accédez à votre .sh. sixième: éditez votre section de commande pour:

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

septième: cliquez sur Ajouter. C'est ça! Fini!

Confirmez maintenant en redémarrant votre PC.

à votre santé!

akbar ali
la source
-1

La méthode indolore, la plus simple et la plus universelle est simplement de l'exécuter avec ~.bash_profileou ~.profile (si vous n'avez pas le fichier bash_profile) .

Ajoutez simplement la commande d'exécution au bas de ce fichier et elle sera exécutée au démarrage du système.

J'ai celui-ci en bas un exemple; ~\Desktop\sound_fixer.sh

Juko
la source
2
C'est inexact. ~/.bash_profiles'exécute lorsque l'utilisateur se connecte - pas au démarrage du système. Dans la question d'origine, l'intention est d'exécuter un serveur d'application Node.js au démarrage de la machine. Votre solution nécessiterait qu'un utilisateur humain se connecte d'abord à la machine avant l'exécution du serveur Node.js. Et, si une sorte de problème provoque un redémarrage du serveur pendant la nuit, l'application ne reviendra jamais à la vie jusqu'à ce que l'humain se
reconnecte
-6

Pour certaines personnes, cela fonctionnera:

Vous pouvez simplement ajouter la commande suivante dans SystèmePréférencesApplications de démarrage :

bash /full/path/to/your/script.sh
SagarSave
la source
Je ne vois pas cela dans le menu des préférences système. Mais je le vois quand je recherche dans le lanceur d'applications.
OKGimmeMoney
Cela ne fonctionne pas réellement au démarrage, mais à la connexion, ce qui est une très grande différence. Cela dépend également d'une certaine configuration, car vous n'aurez pas "Système> Préférences" sur chaque système (en particulier les serveurs).
jazzpi
3
Cette réponse semble plus pour le bureau Ubuntu / Linux, mais l'utilisateur demande en fait de l'aide pour une instance Linux AWS EC2, qui, à ma connaissance, n'a pas d'interface graphique.
Vini.g.fer