Executar um script apenas na primeira inicialização

12

Existe uma maneira idiomática no Ubuntu para executar um script apenas na primeira vez em que uma máquina é inicializada? (EC2)

Roberto Aloi
fonte

Respostas:

14

Não. Mas você pode colocar seu script /etc/init.d/scripte excluí-lo automaticamente:

#!/bin/bash

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

# Delete me
rm $0
Andrejs Cainikovs
fonte
Observe que $0é específico do bash (versão> = 3). Para a finalidade da compatibilidade você pode fornecer nome do arquivo script em vez, tornando este menos genérica:rm /etc/init.d/script
Andrejs Cainikovs
4
$ 0 NÃO é específico do bash e foi suportado por muito mais tempo do que o bash 3.x existe (e é suportado no Bourne, Korn, zsh e outros). O ponto de discórdia é se $ 0 contém uma especificação de caminho completo ou relativo. Aqui está um link para uma maneira confiável de obter o caminho completo, se você precisar: stackoverflow.com/questions/4774054/…
Jim Dennis
7

Crie um arquivo de rastreamento quando o script for executado. Se o arquivo já existir, saia do script.

Tom
fonte
3
Embora possa não parecer tão à primeira vista, essa pode ser uma solução melhor do que excluir o script, pois mantém a possibilidade de acioná-lo novamente, se você desejar.
msanford
7

Combinando as duas primeiras respostas Supondo que você nomeie seu script, /usr/local/bin/firstboot.shcoloque-o no final de /etc/rc.local(esses scripts são executados a cada inicialização), os scripts são assim

#! / bin / bash

FLAG = "/ var / log / firstboot.log"
E se [ ! -f $ FLAG]; então
   #Coloque aqui suas frases de inicialização
   eco "Esta é a primeira inicialização"

   #the next line cria um arquivo vazio para não executar a próxima inicialização
   toque em $ FLAG
outro
   eco "Não faça nada"
fi
Awi
fonte
Isso não está necessariamente funcionando com o sysmtemd. Preciso adicionar um sono 20 para garantir que seja o último script executado.
Mrossi 02/12/19
Se você der o nome /etc/rc.local/99-firstboot.sh, ele deverá ser executado por último.
precisa
3

Estou surpreso com os resultados que estou procurando ao procurar um gancho de "primeira inicialização" do Ubuntu bem definido e suportado. Parece que o público da Red Hat / Fedora / CentOS tem esse problema há mais de uma década. O equivalente mais próximo do Ubuntu parece ser oem-config-firstboot .

A idéia de simplesmente executar um rm $0irá funcionar. Mas, tecnicamente, existem algumas semânticas interessantes envolvidas. Diferentemente da maioria dos outros intérpretes de script no Unix, um script de shell é lido e processado uma linha / instrução de cada vez. Se você desvincular ( rm) o arquivo dele, então a instância do shell que está processando esse script está agora trabalhando com um arquivo anônimo (qualquer arquivo que esteja aberto, mas não desvinculado).

Considere um arquivo 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

Se você salvar isso em algo como rmself.she vincular algo a algo assim tst, a execução ./tstdeverá mostrar algo como isso na saída:

$ ./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

Agora, existem alguns casos de canto possíveis ímpares com relação a links simbólicos e casos em que o script foi chamado como um nome simples (forçando o shell a procurar $PATHo script).

Mas parece que bash(pelo menos na versão 3.2) precede $0o caminho se ele pesquisou o caminho e deixa $ 0 definido como qualquer caminho relativo ou absoluto usado para invocar o script. Parece não fazer nenhum caminho relativo à normalização ou resolução, nem links simbólicos.

Provavelmente, o "firstboot" mais limpo para o Ubuntu seria criar um pequeno pacote (.deb) contendo um script a ser colocado /etc/init.d/firstboote um script de pós-instalação usado update-rc.dpara vinculá-lo ao nível de execução 1 ( /etc/rc1.d) (usando um comando como:) update-rc.d firstboot defaults. .. e faça com que a última linha execute uma desativação ou exclusão usando algo como:update-rc.d firstboot disable

Aqui está um link para o HOWTO Debian update-rc.d

Jim Dennis
fonte
0

Você pode fazer backup do rc.local atual em rc.local.bak

Depois, você pode ter o que deseja fazer no rc.local e, no final, apenas mv /etc/rc.loca.bak /etc/rc.local.

lmojzis
fonte
0

A questão era sobre a execução de um script na primeira inicialização do EC2. Você pode usar cloud-initpara esse fim.

Ao iniciar uma nova instância do EC2, você tem uma opção para definir User dataem Advanced datails. Se você colocar o cloud-initscript lá, ele será executado apenas na primeira inicialização.

Por exemplo, você pode colocar o seguinte em User data:

#cloud-config

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

A saída será gravada em /var/log/cloud-init-output.log

Cloud-initpode fazer muito mais do que isso. Ele foi projetado especialmente para executar a inicialização precoce de instâncias da nuvem. Consulte os documentos aqui: http://cloudinit.readthedocs.io/en/latest/index.html

Dima L.
fonte