web-dev-qa-db-ja.com

初回起動時にのみスクリプトを実行する

Ubuntuには、マシンの初回起動時にのみスクリプトを実行する慣用的な方法がありますか? (EC2)。

12
Roberto Aloi

いいえ。ただし、スクリプトを/etc/init.d/scriptに配置して、自己削除することもできます。

#!/bin/bash

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

# Delete me
rm $0
14

スクリプトの実行時に追跡ファイルを作成します。ファイルが既に存在する場合は、スクリプトを終了します。

7
Tom

最初の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 
7
Awi

明確に定義され、サポートされている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 へのリンクはこちらです

3
Jim Dennis

問題は、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

0
Dima L.

現在のrc.localをrc.local.bakにバックアップできます

次に、rc.localでやりたいことを実行し、最後にmv /etc/rc.loca.bak /etc/rc.localを実行します。

0
lmojzis