【问题标题】:How to start a Linux service (Bash script) containing an infinite loop in the start method如何在启动方法中启动包含无限循环的 Linux 服务(Bash 脚本)
【发布时间】:2013-11-13 12:41:01
【问题描述】:

我正在尝试每 10 分钟检查一次我的某个进程是否正在运行,如果没有,请重新启动该进程。我希望这个脚本在系统启动时自动启动,所以我选择services in Linux

这就是我所做的:

  • 将 Bash 脚本编写为服务。
  • 在shell的start方法中 脚本,在无限循环中,检查是否存在临时文件。 如果可用,请按照我的逻辑,否则打破循环。
  • stop 方法中, 删除临时文件。
  • 然后我使用 update-rc.d 将此脚本添加到 系统启动。

一切正常,除了一件事。如果我执行./myservice start,那么终端会挂起(它应该运行一个无限循环),但如果我执行ctrl-z,那么脚本将被终止,我的任务将无法执行。如何使此脚本从终端启动并正常执行? (例如,./etc/init.d/mysql start)。也许在后台执行该过程并返回。

我的 Bash 脚本如下:

#!/bin/bash

# Start the service
start() {

    #Process name that need to be monitored
    process_name="mysqld"

    #Restart command for process
    restart_process_command="service mysql start"

    #path to pgrep command
    PGREP="/usr/bin/pgrep"

    #Initially, on startup do create a testfile to indicate that the process
    #need to be monitored. If you dont want the process to be monitored, then
    #delete this file or stop this service
        touch /tmp/testfile

        while true;
        do

        if [ ! -f /tmp/testfile ]; then
             break
        fi

        $PGREP ${process_name}

        if [ $? -ne 0 ] # if <process> not running
        then
        # restart <process>
        $restart_process_command
        fi

        #Change the time for monitoring process here (in secs)
        sleep 1000

    done
}

stop() {
       echo "Stopping the service"
       rm -rf /tmp/testfile
}
### main logic ###
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        ;;
  restart|reload|condrestart)
        stop
        start
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|reload|status}"
        exit 1
esac
exit 0

【问题讨论】:

  • 脚本没有被杀死,它只是被挂起。输入 bg 将在后台恢复它。

标签: linux bash shell service


【解决方案1】:

在后台执行函数。说:

start)
      start &

而不是说:

start)
      start

【讨论】:

  • 执行此操作时,它不会退出。即使我按 ctrl-z,10 秒后回声仍然出现。
  • @HRM 该函数在后台执行。您需要终止启动此功能的 shell 进程。
  • 我不是 linux 方面的专家。根据您的建议编辑脚本后,从终端窗口,./myservice start..它只是无限运行..我想要的是执行这个背景并释放该终端。它没有发生。我说清楚了吗?
  • @HRM 如果是 阻止 终端,那可能是由于mysql service start。将该命令也放在后台。 mysql service start &amp;
  • @HRM:检查上述答案中的 start &gt;/dev/null 2&gt;&amp;1 &amp; 是否对您有用。我猜你希望服务完全脱离终端......
【解决方案2】:

在我看来,使用cron 调度程序来调度这种脚本而不是编写独立的初始化脚本是值得的。

cat > /usr/local/bin/watch-mysql.sh <<-"__SEOF__"
    #!/bin/sh
    set -e

    # if this file exists monitoring is stopped
    if [ -f /var/run/dont-watch-mysql.lck ]; then
      exit 0
    fi

    process_name="mysqld"        
    restart_process_command="service mysql restart"
    PGREP="/usr/bin/pgrep"

    $PGREP ${process_name}

    if [ $? -ne 0 ] # if <process> not running
    then
        # restart <process>
        $restart_process_command
    fi
__SEOF__

# make the script executable
chmod u+x /usr/local/bin/watch-mysql.sh

# schedule the script to run every 10 minutes
(crontab -l ; echo "*/10 * * * * /usr/local/bin/watch-mysql.sh") | uniq - | crontab -

如果您只是创建文件/var/run/watch-mysql.lck,它将不会被监控。

【讨论】:

    【解决方案3】:

    您应该将循环本身分离到一个分离的脚本中,并根据您的非自守护应用程序分发中首选的方式从启动脚本运行后一个脚本。

    请注意,即使不是从终端运行,您当前的启动脚本也可能会挂起系统启动,至少对于大多数传统的启动(我不会说 systemd 和其他可以并行启动多个脚本的现代启动,但他们肯定会认为启动还没有完成)。但是你可能会错过它,例如通过 ssh 登录,因为 sshd 将在您的脚本之前启动。

    【讨论】:

    • 但是我已经尝试重新启动并且脚本正在运行。所以你的意思是,没有办法使用单个脚本来完成我的任务。
    • @HRM 实际上这可能是同一脚本 file 中的代码,例如括号中的函数甚至语句序列;在后台启动块之后添加“&”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2016-06-09
    • 2015-02-06
    • 2015-11-02
    相关资源
    最近更新 更多