我对 Upstart 事件上作业的启动方式有些困惑。为了说明我的误解,我有四个 Upstart 作业,如下所示:
工作 1:
start on local-filesystems
task
script
echo "job 1 ran" >> /tmp/job1
end script
工作 2:
start on (local-filesystems and net-device-added)
task
script
echo "job 2 ran" >> /tmp/job2
end script
工作 3:
start on (local-filesystems and bluetooth-device-added)
task
script
echo "job 3 ran" >> /tmp/job3
end script
工作 4:
start on local-filesystems or (local-filesystems and net-device-added) or (local-filesystems and bluetooth-device-added)
task
script
echo "job 4 ran" >> /tmp/job4
end script
我期望重新启动后文件内容如下:
/tmp/job1:
job 1 ran
/tmp/job2
job 2 ran
/tmp/job3
job 3 ran
/tmp/job4
job 4 ran
job 4 ran
job 4 ran
我预计作业 4 会运行三次,因为它可以由三组不同的事件启动,而其他作业也证明了这些事件都会发生。但我的预期是不正确的;这些文件实际上包含以下内容:
/tmp/job1:
job 1 ran
/tmp/job2
job 2 ran
/tmp/job3
job 3 ran
/tmp/job4
job 4 ran
为什么即使所有三组事件都在发生,作业 4 也只运行一次?有没有办法实现在发生任何信号时运行此作业的行为,而不管作业实际运行了多少次?如果有帮助,我对其进行了编辑以打印出 $UPSTART_EVENTS 变量,以查看哪些事件导致了作业 4 及其本地文件系统。
总结一下:我希望作业 4 在 local-filesystems 事件和 net-device-added 事件(只要 local_filesystems 也发生)以及 bluetooth-device-added 事件(只要 local_filesystems 发生)上运行。我该如何实现这一点?
谢谢你!
答案1
start on
仅将作业的目标从停止更改为启动。如果作业已处于 状态start
,则作业不会被锁定,并且不会对启动中的事件执行任何操作。
如果您希望它运行多次,您可以添加以下内容:
instance $UPSTART_EVENTS
有了该 upstart,它将针对匹配的每个事件对运行一个作业实例start on
。
答案2
显而易见但不太优雅的解决方案是创建 3 个不同的 upstart 作业。您只需使用上面创建的作业 1-3。我在虚拟机中研究了一些,这是我能想到的最好的办法。如果有人有更优雅的解决方案,我很乐意看到它。
答案3
答案很简单,如果作业已经代表运行,则您无法响应多个事件任何上述情况。Upstart 不会记录和重放事件。如果您的作业由于事件 A 而运行,并且事件 A 启动,则会发生事件 B,该作业也可以对此做出响应。没有队列会保存事件 B 并将其重放到之前运行的每个作业以再次评估该事件。毕竟,这是 init,而 init 脚本的目标通常是运行一次。
启动图将很容易地显示同时发出的信号。
您可以通过配置作业以响应事件来自己验证这一点,使其执行一些简单操作,例如休眠 30 秒,然后在作业运行时发出另一个 (initctl emit foo) 事件。作业第一次运行完成后,将不会再次运行。
“总结一下:我希望作业 4 在本地文件系统事件和网络设备添加事件(只要本地文件系统也发生)以及蓝牙设备添加事件(只要本地文件系统发生)上运行。我该如何实现呢?”
http://upstart.ubuntu.com/cookbook/#starting-a-job
它实际上非常清楚地说明了这种条件执行。但这并不意味着它会运行多次。您可能希望重新考虑以这种方式解决这个问题。