我在bash中有一个简短的脚本,它需要在后台运行。 它基于inotifywait,它应该等待指定文件夹的更改,如果有任何更改,它应该运行复制过程。
#! /bin/sh case "$1" in start) dir=/var/www/www/source/ target=/var/www/www/htdocs/application/cache/target/ inotifywait -m "$dir" --format '%w%f' -e close_write | while read file; do cp "$file" "$target" done ;; stop) ;; esac
我已经把它放在/etc/init.d,保存后运行update-rc.d myscript默认 ,但是现在,当我尝试启动它时,会抛出服务启动命令,停止从inotifywait的消息中停止。
/etc/init.d/bash start Setting up watches. Watches established.
你可以给我一些提示如何在后台进程没有任何输出消息(在启动后立即以理想的方式)运行它?
所以我得到了这个工作,但它是一个非常丑陋的黑客。 对于如何正确编写init脚本,我build议这个链接 。
我想要做的只是把这个过程放在后台用“&”。
/etc/init.d/myinitscript.sh #! /bin/sh case "$1" in start) dir=/var/www/www/source/ target=/var/www/www/htdocs/application/cache/target/ inotifywait -m "$dir" --format '%w%f' -e close_write | while read file; do cp "$file" "$target" done & ## <--- why not just put it in the background? ;; stop) ;; esac
这个“工作”…对于某些“工作”的价值。 “myinitscript.sh”开始运行,并做它应该做的,但结果在这个挂起的过程:
$ ps aux | grep -i init [... snip ...] root 2341 0.0 0.1 4096 600 ? Ss 18:02 0:00 startpar -f -- myinitscript.sh [... snip ...]
这个问题的原因和可能的解决scheme可以在这里find 。
我后来的解决办法很丑,如果你在生产中这样做,那么你做错了。
我使用两个脚本,一个在/etc/init.d,另一个在/ root。
/etc/init.d/myinitscript.sh #! /bin/sh case "$1" in start) /root/initscriptbody.sh > /dev/null 2>&1 ;; stop) ;; esac
不要将stdout和stderrredirect到/ dev / null结果挂在“starpar”进程中。 第二个脚本包含了所有的function,它可以放在后台,而不会导致挂起的'starpar'过程:
/root/initscriptbody.sh #! /bin/sh dir=/var/www/www/source/ target=/var/www/www/htdocs/application/cache/target/ inotifywait -m "$dir" --format '%w%f' -e close_write | while read file do cp "$file" "$target" done & ## <-- no problem backgrounding this now
您可以使用屏幕 ,或按照评论中的build议, nohup 。 可以以自动方式使用,例如使用init脚本。
在屏幕的情况下,您可能需要格外小心,如果从初始化脚本中使用它,它将成功地打开一个屏幕会话。 具体设置正确的$ TERM环境并将其作为特定用户运行。
如果正确完成,它将附加到屏幕会话并将其分离。 虽然为了您的特定目的屏幕可能有点矫枉过正。
还要看看/etc/init.d/skeleton ,它提供了一个模板来创buildinit脚本。
下面一行, do_start()函数的一部分可能只是做你需要的:
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON
你只需要在开始时改变variables来指向你的脚本和相关的东西,它可以按原样运行。
一种可能的方法是使用Daemontools来启动你的bash脚本。 Daemontools是一个控制脚本执行的守护进程 – 监听它的stdout,如果退出则重新启动。 还有一些替代scheme,如supervisord或使用Systemd服务单元运行脚本