我托管了一个实验/测试 Linux 机器,运行 Debian Wheezy 7.4.0 发行版。不同的用户通过 ssh 登录到他们的帐户,并被允许运行开发工具,如果他们愿意,可以让他们的程序作为服务在后台运行。
由于这是一台用于各种目的的测试机器,因此经常需要重新启动整个机器,然后用户必须重新登录并重新启动正在运行的用户空间内容。我想使这一过程自动化。基本上,我想为用户提供一种在机器启动后立即启动内容的方法(在所有其他内容都初始化之后),以及一种在系统关闭时启动内容的方法(没有时间限制,基本上是暂停关闭,直到所有关闭的用户进程都完成)。
到目前为止我已经尝试过:
我创建了一个 init bash 脚本,遵循 /etc/init.d/ 下的“skeleton”模板文件中的原则(Skeleton 模板源代码:https://gist.github.com/ivankovacevic/9917139)
我的代码在这里: https://github.com/ivankovacevic/userspaceServices
基本上,脚本会遍历用户主目录并在名为 .startUp、.shutDown 或 .status 的相应子目录中查找可执行文件。根据当前正在发生的事件,脚本将执行苏就像用户自己启动它们一样。
我目前面临的问题是,系统启动后会有一个奇怪的进程挂起,并且脚本会启动其他用户的所有进程。它在进程列表中的样子如下:
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 3053 1 0 1024 620 1 17:42 ? 00:00:00 startpar -f -- userspaceServices
我不知道该进程是什么,它的手册页也没有提到 -f 参数。所以我一无所知,但我肯定做错了什么,因为 init.d 中的其他脚本/服务都没有在启动后让这样的进程挂起。
因此,我正在寻找某人来帮助我调试我拥有的这个解决方案(在我看来,这也有点复杂)。或者给我一些想法,告诉我如何以完全不同的方式实现它。
更新
我已经针对启动器问题:
从 rc.local 或 init.d 启动进程时 startpar 进程挂起
更新2
我原来的解决方案解决了问题。检查前面提到的问题启动器。GitHub 上的代码也进行了修正以反映这一点。
更新 3-如何使用 crontab
正如 Jenny 所建议的,普通用户可以使用 crontab 安排在启动时执行一次任务。如果您只需要在启动时启动用户任务而不是关机,我发现这是最简单的方法。但是有一个缺点,即用户在启动正在进行的类似服务的任务时,可能会让 cron 进程作为父进程“挂起”。首先让我解释一下它的工作原理:
普通用户自己应该拨打:
crontab -e
(-e 就像编辑) 这将打开一个默认控制台文本编辑器,其中包含用户 crontab 文件。要添加要在启动时执行的任务,用户必须在文件末尾添加一行:
@reboot /path/to/the/executable/file
现在,如果用户这样做,并且如果该文件不仅仅是一些线性完成某件事并结束的简单脚本,而是某种看门狗,那么在重新启动后,您将在进程列表中以如下内容结束:
1 2661 root 20 0 20380 860 660 S 0.0 0.0 0:00.00 ├─ /usr/sbin/cron
2661 2701 root 20 0 33072 1152 868 S 0.0 0.0 0:00.00 │ └─ /USR/SBIN/CRON
2701 2944 someuser 20 0 4180 580 484 S 0.0 0.0 0:00.00 │ └─ /bin/sh -c ./watchdog
2944 2945 someuser 20 0 10752 1204 1016 S 0.0 0.0 0:00.00 │ └─ /bin/bash ./watchdog
2945 2946 someuser 20 0 23696 4460 2064 S 0.0 0.1 0:00.01 │ └─ /usr/bin/python ./some_program.py
为了避免这种情况,用户需要修改他的 crontab 条目使其看起来像这样:
@reboot /path/to/the/executable/file >/dev/null 2>&1 &
文件描述符的重定向是可选的,但建议保持干净。如果你想研究原因,请尝试查看它们:
ls -l /proc/pid_of_started_process/fd
答案1
我同意你的解决方案看起来有点复杂,所以我会选择“给我一些想法如何以完全不同的方式实现它”:-)
标准解决方案是使用配置管理系统(例如 puppet),并允许用户将他们的内容添加到服务器的 puppet 配置中。然后,Puppet 将推出启动脚本并将其添加到相关运行级别。
更快捷的方法是授予他们 sudoedit 访问权限
/etc/rc.d/rc.local
并将他们的东西添加到那里。或者给他们每个目录来放置他们想要启动的启动脚本,并让 cron 作业将这些脚本复制到
/etc/init.d
,插入su $USER -c
到合适的位置并在它们上运行 chkconfig。或者给它们每个目录放置启动脚本,并在末尾添加几行以
/etc/rc.d/rc.local
遍历这些目录并运行編輯su $USER -c 'script start'
其中每个脚本均如此。
编辑后添加:
5. 让他们使用 crontab 来安排要运行的作业@reboot