仅在首次启动时运行脚本


Answers:


14

否。但是您可能想将脚本放在中/etc/init.d/script,然后将其自删除:

#!/bin/bash

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

# Delete me
rm $0

请注意,$0特定于bash(版本> = 3)。出于兼容性目的,您可以提供脚本文件名,以减少通用性:rm /etc/init.d/script
Andrejs Cainikovs 2012年

4
$ 0不是特定于bash的,并且其支持的时间远远超过bash 3.x的支持时间(并且在Bourne,Korn,zsh和其他语言中受支持)。症结在于$ 0是否包含完整或相对路径说明。下面就来获取完整路径的可靠方式的链接,如果你需要它: stackoverflow.com/questions/4774054/...
吉姆·丹尼斯

7

脚本运行时创建一个跟踪文件。如果文件已经存在,请退出脚本。


4
乍一看似乎并不尽如人意,但与删除脚本相比,这可能是一个更好的解决方案,因为如果您愿意的话,它仍然可以再次触发该脚本。
桑福德,2014年

7

结合前两个答案假设您为脚本命名,/usr/local/bin/firstboot.sh则将其放在/etc/rc.local(此脚本在每次启动时运行)的末尾,脚本如下所示

#!/ bin / bash

FLAG =“ / var / log / firstboot.log”
如果[!-f $ FLAG]; 然后
   #将初始化语句放在这里
   回声“这是第一次启动”

   #下一行创建一个空文件,因此它将不会运行下一次启动
   触摸$ FLAG
其他
   回声“什么都不做”
科幻

这不一定与sysmtemd一起使用。我需要添加睡眠20来确保它是最后一个脚本运行。
mrossi '16

如果将其命名为/etc/rc.local/99-firstboot.sh,它将最后运行。
JohnDavid

3

我对搜索定义明确且受支持的Ubuntu“首次启动”钩子的结果感到惊讶。似乎Red Hat / Fedora / CentOS的拥护者对此已经钉牢十多年了。最接近的Ubuntu等效项似乎是oem-config-firstboot

简单执行rm $0遗嘱的想法行得通。但是,从技术上讲,涉及一些有趣的语义。与Unix下大多数其他脚本解释器不同,一次读取和处理shell脚本仅需要一行代码/语句。如果您rm从下面取消链接(),则表示正在处理该脚本的Shell实例现在正在处理一个匿名文件(任何打开但未链接的文件)。

考虑这样的文件:

#!/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”可能是创建一个小包(.deb),其中包含要放置的/etc/init.d/firstboot脚本以及用于update-rc.d将其链接到运行级别1(/etc/rc1.d)的安装后脚本(使用命令:)update-rc.d firstboot defaults。 ..然后使用以下命令使最后一行停用或删除:update-rc.d firstboot disable

这是Debian update-rc.d HOWTO的链接


0

您可以将当前的rc.local备份到rc.local.bak

然后,您可以在rc.local中拥有要执行的操作,最后只需执行mv /etc/rc.loca.bak /etc/rc.local。


0

问题是有关在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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.