Ubuntuには、マシンの初回起動時にのみスクリプトを実行する慣用的な方法がありますか? (EC2)。
いいえ。ただし、スクリプトを/etc/init.d/script
に配置して、自己削除することもできます。
#!/bin/bash
echo "Bump! I'm your first-boot script."
# Delete me
rm $0
スクリプトの実行時に追跡ファイルを作成します。ファイルが既に存在する場合は、スクリプトを終了します。
最初の2つの回答を組み合わせるスクリプトに/usr/local/bin/firstboot.sh
という名前を付けた場合、/etc/rc.local
の最後に配置すると(このスクリプトはすべてのブートで実行されます)、スクリプトは次のようになります
#!/ bin/bash FLAG = "/ var/log/firstboot.log" if [! -f $ FLAG]; then #ここに初期化文を入力してください echo "これが最初のブートです" #次の行は空のファイルを作成し、実行されません次のブート タッチ$ FLAG else echo "何もしない" fi
明確に定義され、サポートされているUbuntuの「最初のブート」フックを検索した結果に驚きました。 Red Hat/Fedora/CentOSの群衆は10年以上にわたってこれを打ち付けてきたようです。 Ubuntuで最も近いものは oem-config-firstboot のようです。
単純にrm $0
を実行するというアイデアはうまくいきます。しかし、技術的にはいくつかの興味深い意味論が関係しています。 Unixの他のほとんどのスクリプトインタープリターとは異なり、シェルスクリプトは一度に1行/文ずつ読み取られて処理されます。その下からファイルのリンクを解除(rm
)すると、そのスクリプトを処理しているシェルのインスタンスが匿名ファイル(開いているがリンクされていないファイル)で動作するようになります。
次のようなファイルを考えてみましょう。
#!/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
rmself.sh
のようなものに保存し、tst
のようなものに(ハード)リンクすると、./tst
を実行すると次のような出力が表示されます。
$ ./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
これで、シンボリックリンクに関する奇妙な可能性のあるコーナーケースと、スクリプトが裸の名前として呼び出されたケースがいくつかあります(シェルがスクリプトの$PATH
を検索するように強制します)。
ただし、bash
(少なくともバージョン3.2では)がパスを検索した場合、$0
の前にパスが追加され、それ以外の場合はスクリプトの呼び出しに使用された相対パスまたは絶対パスに$ 0が設定されます。正規化や解決の相対パスやシンボリックリンクは行わないようです。
おそらくUbuntuで最もクリーンな「firstboot」は、/etc/init.d/firstboot
に配置されるスクリプトと、update-rc.d
を使用してランレベル1にリンクするポストインストールスクリプトを含む小さなパッケージ(.deb)を作成することです。 (/etc/rc1.d
)(次のようなコマンドを使用します:update-rc.d firstboot defaults
)...そして、最後の行でupdate-rc.d firstboot disable
のようなものを使用して非アクティブ化または削除します。
Debian update-rc.d HOWTO へのリンクはこちらです
問題は、EC2の最初のブート時にスクリプトを実行することでした。この目的でcloud-init
を使用できます。
新しいEC2インスタンスを起動するとき、User data
の下にAdvanced datails
を定義するオプションがあります。 cloud-init
スクリプトをそこに配置すると、最初の起動時にのみ実行されます。
たとえば、次をUser data
に配置できます。
#cloud-config
runcmd:
- /usr/bin/command1.sh
- /usr/bin/command2.sh
出力は/var/log/cloud-init-output.log
に書き込まれます
Cloud-init
はこれ以上のことができます。特に、クラウドインスタンスの初期初期化を実行するように設計されています。こちらのドキュメントをご覧ください: http://cloudinit.readthedocs.io/en/latest/index.html
現在のrc.localをrc.local.bakにバックアップできます
次に、rc.localでやりたいことを実行し、最後にmv /etc/rc.loca.bak /etc/rc.localを実行します。