Ejecute un script solo en el primer arranque

12

¿Hay alguna forma idiomática en Ubuntu para ejecutar un script solo la primera vez que se inicia una máquina? (EC2).

Roberto Aloi
fuente

Respuestas:

14

No. Pero es posible que desee colocar su script /etc/init.d/scripty eliminarlo automáticamente:

#!/bin/bash

echo "Bump! I'm your first-boot script."

# Delete me
rm $0
Andrejs Cainikovs
fuente
Tenga en cuenta que $0es específico de bash (versión> = 3). Para fines de compatibilidad, puede proporcionar el nombre del archivo de script en su lugar, lo que lo hace menos genérico:rm /etc/init.d/script
Andrejs Cainikovs
44
$ 0 NO es específico de bash y ha sido compatible durante mucho más tiempo que bash 3.x ha existido (y es compatible con Bourne, Korn, zsh y otros). El problema es si $ 0 contiene una especificación de ruta completa o relativa. Aquí hay un enlace a una forma confiable de obtener la ruta completa si la necesita: stackoverflow.com/questions/4774054/…
Jim Dennis
7

Cree un archivo de seguimiento cuando se ejecute el script. Si el archivo ya existe, salga del script.

Tom
fuente
3
Si bien puede no parecerlo a primera vista, esta puede ser una mejor solución que eliminar el script, ya que conserva la posibilidad de activarlo nuevamente, si alguna vez lo desea.
msanford
7

Combinando las dos primeras respuestas Asumiendo que nombras tu script /usr/local/bin/firstboot.shponlo al final de /etc/rc.local(este script se ejecuta en cada arranque) los scripts son así

#! / bin / bash

FLAG = "/ var / log / firstboot.log"
Si [ ! -f $ BANDERA]; luego
   #Ponga aquí sus oraciones de inicialización
   echo "Esta es la primera bota"

   # la siguiente línea crea un archivo vacío para que no se ejecute el próximo arranque
   toque $ BANDERA
más
   echo "No hacer nada"
fi
Awi
fuente
Esto no necesariamente funciona con sysmtemd. Necesito agregar un sleep 20 para asegurarme de que sea la última secuencia de comandos ejecutada.
mrossi
Si lo nombra /etc/rc.local/99-firstboot.sh, debería ejecutarse en último lugar.
JohnDavid
3

Estoy sorprendido por los resultados que estoy viendo para buscar un gancho de "primer arranque" de Ubuntu bien definido y compatible. Parece que la multitud de Red Hat / Fedora / CentOS ha tenido esto clavado por más de una década. El equivalente más cercano de Ubuntu parece ser oem-config-firstboot .

La idea de simplemente realizar un rm $0testamento funcionará. Pero, técnicamente, hay algunas semánticas interesantes involucradas. A diferencia de la mayoría de los otros intérpretes de script en Unix, un script de shell se lee y procesa una línea / declaración a la vez. Si desvincula ( rm) el archivo de debajo, entonces la instancia del shell que procesa ese script ahora está trabajando con un archivo anónimo (cualquier archivo que esté abierto pero no vinculado).

Considere un archivo como este:

#!/bin/bash
rm $0
echo "I've removed myself: $0"
ls -l $0
cat <<COMMENTARY
   This is a test.
   I'm still here, because the "here" doc is being fed to 'cat'
   via the anonymous file through the open file descriptor.
   But I cannot be re-exec'd
COMMENTARY
exec $0

Si guarda eso en algo como rmself.shy lo vincula (de forma rígida) a algo así tst, la ejecución ./tstdebería mostrar algo como esto como salida:

$ ./tst 
I've removed myself: ./tst
ls: ./tst: No such file or directory
   This is a test.
   I'm still here, because the "here" doc is being fed to 'cat'
   via the anonymous file through the open file descriptor.
   But I cannot be re-exec'd
./tst: line 11: /home/jimd/bin/tst: No such file or directory
./tst: line 11: exec: /home/jimd/bin/tst: cannot execute: No such file or directory

Ahora hay algunos casos de esquina posibles con respecto a los enlaces simbólicos y casos en los que se invocó el script como un nombre simple (lo que obliga al shell a buscar $PATHel script.

Pero parece que bash(al menos en la versión 3.2) antepone $0la ruta si buscó la ruta y de lo contrario deja $ 0 establecido en la ruta relativa o absoluta que se utilizó para invocar el script. No parece hacer ninguna ruta relativa de normalización o resolución ni enlaces simbólicos.

Probablemente, el "primer arranque" más limpio para Ubuntu sería crear un pequeño paquete (.deb) que contenga un script para colocarlo /etc/init.d/firstbooty un script posterior a la instalación que se usa update-rc.dpara vincular eso en el nivel de ejecución 1 ( /etc/rc1.d) (usando un comando como:) update-rc.d firstboot defaults. .. y luego haga que la última línea realice una desactivación o eliminación usando algo como:update-rc.d firstboot disable

Aquí hay un enlace al COMO de Debian update-rc.d

Jim Dennis
fuente
0

Puede hacer una copia de seguridad de rc.local actual en rc.local.bak

Entonces puede tener las cosas que desea hacer en rc.local y al final solo mv /etc/rc.loca.bak /etc/rc.local.

lmojzis
fuente
0

La pregunta era sobre ejecutar un script en el primer arranque de EC2. Puedes usar cloud-initpara este propósito.

Al iniciar una nueva instancia de EC2, tiene una opción para definir User dataen Advanced datails. Si coloca el cloud-initscript allí, se ejecutará solo en el primer arranque.

Por ejemplo, puede colocar lo siguiente en User data:

#cloud-config

runcmd:
  - /usr/bin/command1.sh
  - /usr/bin/command2.sh

La salida se escribirá en /var/log/cloud-init-output.log

Cloud-initpuede hacer mucho más que esto. Está diseñado especialmente para realizar una inicialización temprana de instancias en la nube. Vea los documentos aquí: http://cloudinit.readthedocs.io/en/latest/index.html

Dima L.
fuente