Cómo ejecutar un script de shell al inicio

367

En una instancia de Amazon S3 Linux, tengo dos scripts llamados start_my_appy stop_my_appque comienzan y se detienen para siempre (que a su vez ejecuta mi aplicación Node.js). Utilizo estos scripts para iniciar y detener manualmente mi aplicación Node.js. Hasta aquí todo bien.

Mi problema: también quiero configurarlo para que start_my_appse ejecute siempre que el sistema se inicie. Sé que necesito agregar un archivo dentro init.dy sé cómo vincularlo al directorio apropiado dentro rc.d, pero no puedo entender lo que realmente necesita ir dentro del archivo que coloco init.d. Estoy pensando que debería ser solo una línea start_my_app, pero eso no me ha funcionado.

meetamit
fuente
55
No soy experta en este tipo de cosas, pero creo que la init.dsolución ( aquí ) debería preferirse a la rc.localsolución porque esta última es la herramienta antigua que todavía es utilizable porque la nueva herramienta es compatible con versiones anteriores.
erikbwork
pm2 iniciar my_app; inicio pm2; pm2 save github.com/Unitech/pm2
Unitech

Respuestas:

292

En el archivo que ingresas /etc/init.d/debes configurarlo como ejecutable con:

chmod +x /etc/init.d/start_my_app

Gracias a @meetamit, si esto no se ejecuta, debe crear un enlace simbólico para /etc/rc.d/

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

Tenga en cuenta que en Debian más reciente, esto no funcionará ya que su script debe ser compatible con LSB (proporcione, al menos, las siguientes acciones: inicio, detención, reinicio, forzar recarga y estado): https: //wiki.debian .org / LSBInitScripts

Como nota, debe colocar la ruta absoluta de su script en lugar de una relativa, ya que puede resolver problemas inesperados:

/var/myscripts/start_my_app

Y no olvides agregar encima de ese archivo:

#!/bin/sh
Jonathan Muller
fuente
66
Hice esto y no funcionó. ¿se ejecutará automáticamente solo porque está en /etc/init.d o necesito hacer algo en la parte superior para programar que se ejecute cuando se inicie el sistema?
anfibio
44
@amphibient No es suficiente ... También necesita crear un enlace simbólico a este archivo (usando el lncomando) a un directorio dentrorc.d
meetamit
23
no hay un directorio rc.d en mi carpeta raíz, etc. Esto me tiene atónito ¿no es este un directorio crucial que Linux necesita para iniciarse? Solo falta un sistema operativo que parece funcionar bien. ¿Tengo que crearlo? Veo un montón de archivos con nombres similares como "rc1.d" hasta "rc5.d"
OKGimmeMoney
3
No tienen ninguna /etc/rc.dcarpeta, pero tengo /etc/rcX.dcarpetas (Ie /etc/rc0.d , /etc/rc1.d , /etc/rcS.d ), también hay un archivo /etc/rc.local . Creo que debería crear enlaces simbólicos en una carpeta personalizada como /etc/rc9.do en una de las existentes ... (Ubuntu Server 14.04)
F8ER
2
Esta pregunta me ayudó con esto: unix.stackexchange.com/questions/28679/…
seth10
344

Establecer un crontab para esto

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

después de cada inicio, ejecutará el script de prueba.

Hemant kumar
fuente
44
¡Esta es la única solución que funcionó para mí sin problemas! gracias
whoopididoo
20
Esta es la mejor solución, @reboot sh $HOME/test.shen el crontab está aún más limpio
usuario3667089
44
@ user3667089 en realidad, no está funcionando. Abro la terminal, ingreso "crontab -e", aparece una ventana, donde escribo en "@reboot sh /home/user/test.sh" pero no se ejecuta al inicio. ¿Dónde lo estoy haciendo mal?
MycrofD
1
@ user3667089 las líneas predeterminadas habituales '# Editar este archivo a ...' y luego la línea que escribí '@reboot sh /home/.../.sh'. También probé '@reboot /home/.../.sh' sin la "sh" inicial pero sin resultados.
MycrofD
3
@MycrofD crontab -ldebería aparecer @reboot sh $HOME/test.shpara confirmar que realmente se ha configurado.
user3667089
124

Un enfoque simple es agregar una línea en /etc/rc.local:

/PATH/TO/MY_APP &

o si desea ejecutar el comando como un usuario especial:

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

(el signo & comercial sigue el proceso y permite que rc.local continúe ejecutándose)

Si desea un script de inicio completo, la distribución de Debian tiene un archivo de plantilla, por lo que:

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

y adaptarlo un poco.

Gilles Quenot
fuente
2
¡Gracias! Este enfoque resultó funcionar mejor dados los requisitos simples. Estoy bastante seguro de que necesitaba especificar el usuario, de lo contrario, cuando tuviera que detener manualmente la aplicación (ejecutando stop_my_app) tendría que hacerlo sudo, ¿no? Además, me pregunto cuál es exactamente la función del signo de unión (?).
meetamit
3
El usuario depende de su aplicación. Pero si no es absolutamente necesario que se ejecute como root, evítelo. &ejecutar el proceso en segundo plano
Gilles Quenot
2
sputnick, lo siento, pero debo marcar Koren como la respuesta aceptada, principalmente por lo que señaló @ erikb85, pero también porque mi pregunta original preguntaba por la init.dforma de hacer las cosas (su respuesta fue solo una solución más simple para mí en ese momento) . Esta publicación tiene muchas opiniones y votos, por lo que es importante mantener la precisión.
meetamit el
44
Parece que no se menciona que el signo final y el fondo del proceso permiten que rc.local continúe ejecutándose.
mchicago
¡Gracias por esto! Pasé las últimas horas golpeándome la cabeza contra la pared mientras intentaba hacer un servicio, pero nada funcionó. Probé esto, funciona como un encanto!
Marko Grešak
35

Esta es la forma en que lo hago en los sistemas Red Hat Linux .

Ponga su script /etc/init.d, propiedad de root y ejecutable. En la parte superior del guión, puede dar una directiva para chkconfig. Ejemplo, el siguiente script se usa para iniciar una aplicación Java como usuario oracle.

El nombre del guión es /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

Esto dice que el script debe ejecutarse en los niveles 3, 4 y 5, y la prioridad para iniciar / detener es 99 y 10.

Luego, como usuario root, puede usar chkconfigpara habilitar o deshabilitar el script al inicio:

chkconfig --list apex
chkconfig --add apex

Y puedes usar service start/stop apex.

Saule
fuente
Mientras tanto, he experimentado con un paquete llamado supervisor ( supervisord.org ) que está disponible en el repositorio de epel. Se puede usar para iniciar programas y monitorearlos, reiniciandolos en caso de falla.
Saule
En lugar de escribir: "chkconfig --add service_name" después de colocar el script en la carpeta /etc/init.d/, puede escribir: "chkconfig service_name on"
Dragan Radevic
23

Ingrese cronusando sudo:

sudo crontab -e

Agregue un comando para ejecutar al inicio, en este caso un script:

@reboot sh /home/user/test.sh

Salvar:

Presione ESC y luego: x para guardar y salir, o presione ESC y luego ZZ (eso es shift + zz)

Prueba Prueba Prueba :

  1. Ejecute su script de prueba sin cron para asegurarse de que realmente funcione.

  2. Asegúrese de guardar su comando en cron, use sudo crontab -e

  3. Reinicie el servidor para confirmar que todo funciona sudo @reboot

usuario3140639
fuente
Esto me gusta mucho. ¡Gracias! PD. no lo use sudosi desea ejecutar un determinado comando durante el inicio utilizando el usuario actual.
danger89
¿Dónde se supone que se almacena esta información? No en /tmp??
Peter Mortensen
15

Solo agregue una línea a su crontab.

Asegúrese de que el archivo sea ejecutable:

chmod +x /path_to_you_file/your_file

Para editar el archivo crontab:

crontab -e

Línea que debes agregar:

@reboot  /path_to_you_file/your_file

Así de simple!

Luciano Ghilarducci
fuente
Esto no funciona para mí, ¿me falta algo? # 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
Esto funcionó para mí en CentOs 7. Para aquellos con problemas, necesitaba crear un script de shell, hacerlo ejecutable (chmod + x file_name) y llamar al script de shell desde el cron que a su vez llama al nodo path_to_file / index.js
SeanOlson
11

Otra opción es tener un comando @reboot en su crontab.

No todas las versiones de cron lo admiten, pero si su instancia se basa en la AMI de Amazon Linux, funcionará.

Chris
fuente
6

Puedes hacerlo :

chmod +x PATH_TO_YOUR_SCRIPT/start_my_app 

entonces usa este comando

update-rc.d start_my_app defaults 100

Por favor vea esta página en Cyberciti .

IR PRO
fuente
1
Tengo una configuración bastante básica, basada en yocto y esta fue la única manera de hacer que mi script funcione. Gracias.
Catalin Vasile
3

Crea tu propio ejecutable / init

Esto no es lo que quieres, ¡pero es divertido!

Simplemente elija un archivo ejecutable arbitrario, incluso un script de shell , y arranque el núcleo con el parámetro de línea de comando:

init=/path/to/myinit

Hacia el final del arranque, el kernel de Linux ejecuta el primer ejecutable de espacio de usuario en la ruta dada.

Varios proyectos proporcionan initejecutables populares utilizados por las principales distribuciones, por ejemplo systemd, y en la mayoría de las distribuciones init bifurcará un montón de procesos utilizados en la operación normal del sistema.

Pero podemos secuestrarlo /initpara ejecutar nuestros propios scripts mínimos para comprender mejor nuestro sistema.

Aquí hay una configuración mínima reproducible: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/f96d4d55c9caa7c0862991025e1291c48c33e3d9/README.md#custom-init

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

Esta solución simple funcionó para mí en una instancia de Amazon Linux que ejecuta CentOS. Edite su /etc/rc.d/rc.localarchivo y coloque el comando allí. Se menciona en este archivo que se ejecutará después de todos los demás scripts de inicio. Así que ten cuidado al respecto. Así es como me busca el archivo actualmente. ingrese la descripción de la imagen aquí. La última línea es el nombre de mi script.

shshnk
fuente
1

El método más sencillo si todo lo que desea ejecutar es un script simple (o cualquier otra cosa) es si tiene una interfaz gráfica de usuario para usar el sistema> preferencias y luego iniciar aplicaciones.

solo busque el script que desee y listo. (hacer script ejecutable)

barrendero
fuente
3
En realidad, esto no se ejecuta en el inicio, sino en el inicio de sesión, que es una gran diferencia. También depende de una determinada configuración, ya que no tendrá "Sistema> Preferencias" en todos los sistemas (especialmente en los servidores).
jazzpi
El término de búsqueda 'Linux ejecutar al inicio' me llevó a esta respuesta, que estaba buscando. A pesar de que no responde la pregunta de OP, esto podría ayudar a los novatos de Linux (ubuntu) como yo, por lo que merece un voto positivo. A mí tampoco me gusta, pero eso es pragmatismo.
thymaro
1

Para Debian 9 ver /ubuntu/228304/how-do-i-run-a-script-at-start-up . Me ha ayudado. Versión corta para Debian 9: agregue comandos (como root) a /etc/rc.local

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

Probablemente, /path_to_file/filename.sh debería ser ejecutable (creo que sí).

Mikhail Ionkin
fuente
1

En Lubuntu tuve que lidiar con la situación opuesta. Skype comenzó a ejecutarse después de arrancar y encontré en ~/.config/autostart/el archivo skypeforlinux.desktop. El contenido del archivo es el siguiente:

[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

Eliminar este archivo me ayudó.

aerijman
fuente
0
  • Agregue su script al directorio /etc/init.d/
  • Actualice sus niveles de ejecución rc: $ update-rc.d myScript.sh defaults NNdonde NN es el orden en que debe ejecutarse. 99, por ejemplo, significará que se ejecutará después de 98 y antes de 100.
Kibrom Gebre
fuente
0

Trabajando con microservicios Python 3 o shell; usando Ubuntu Server 18.04 (Bionic Beaver) o Ubuntu 19.10 (Eoan Ermine) o Ubuntu 18.10 (Cosmic Cuttlefish) Siempre me gustan estos pasos, y siempre funcionó :

  1. Crear un microservicio llamado p ejemplo "brain_microservice1.service" en mi caso:

    $ nano /lib/systemd/system/brain_microservice1.service
  2. Dentro de este nuevo servicio en el que se encuentra:

    [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. Dar los permisos:

    $ chmod -X /lib/systemd/system/brain_microservice*
    $ chmod -R 775 /lib/systemd/system/brain_microservice*
  4. Otorgue el permiso de ejecución entonces:

    $ systemctl daemon-reload
  5. Habilitar entonces, esto hará que siempre comience al inicio

    $ systemctl enable brain_microservice1.service
  6. Entonces puedes probarlo;

    $ sudo reiniciar ahora

  7. Acabado = ÉXITO !!

Esto se puede hacer con la misma secuencia de comandos del cuerpo para ejecutar shell, reaccionar ... secuencia de comandos de inicio de la base de datos ... cualquier código OS ... espero que esto te ayude ...

...

Renan Moura
fuente
0

¡Aquí hay un método más simple!

Primero: escriba un script de shell y guárdelo en .sh aquí hay un ejemplo

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

este script deshabilitará el teclado interno al inicio.

Segundo: abra la aplicación "Preferencias de la aplicación de inicio"

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Tercero: haga clic en Agregar. cuarto: en la sección NOMBRE, dale un nombre. quinto: en la sección de comandos, busque su .sh. sexto: edite su sección de comandos para:

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

séptimo: haga clic en Agregar. ¡Eso es! ¡Terminado!

Ahora confirme reiniciando su PC.

¡salud!

akbar ali
fuente
-1

Sin dolor, el método más fácil y más universal es simplemente ejecutarlo con ~.bash_profileo ~.profile (si no tiene el archivo bash_profile) .

Simplemente agregue el comando de ejecución en la parte inferior de ese archivo y se ejecutará cuando se inicie el sistema.

Tengo este en la parte inferior un ejemplo; ~\Desktop\sound_fixer.sh

Juko
fuente
2
Eso es inexacto. ~/.bash_profilese ejecuta cuando el usuario inicia sesión, no cuando se inicia el sistema. En la pregunta original, la intención es ejecutar un servidor de aplicaciones Node.js al iniciar la máquina. Su solución requeriría que un usuario humano primero inicie sesión en la máquina antes de que se ejecute el servidor Node.js. Y, si algún tipo de problema hace que un reinicio del servidor durante la noche, la aplicación no volver nunca más a la vida hasta los troncos humanos de nuevo.
meetamit
-6

Para algunas personas, esto funcionará:

Simplemente puede agregar el siguiente comando en SistemaPreferenciasAplicaciones de inicio :

bash /full/path/to/your/script.sh
SagarGuardar
fuente
No veo esto en el menú de preferencias del sistema. Pero lo veo cuando busco en el iniciador de aplicaciones.
OKGimmeMoney
En realidad, esto no se ejecuta en el inicio, sino en el inicio de sesión, que es una gran diferencia. También depende de una determinada configuración, ya que no tendrá "Sistema> Preferencias" en todos los sistemas (especialmente en los servidores).
jazzpi
3
Esta respuesta parece más para el escritorio Ubuntu / Linux, pero el usuario en realidad está solicitando ayuda para una instancia de AWS EC2 Linux, que hasta donde yo sé, no tiene GUI.
Vini.g.fer