从bash脚本启动进程失败

一月

我有一个中央服务器,在该服务器中,我定期从cron启动脚本来检查远程服务器。该检查是按顺序执行的,因此首先是一台服务器,然后是另一台服务器。

该脚本(从中央服务器)在远程计算机上启动另一个脚本(将其称为update.sh),并且该脚本(在远程计算机上)正在执行以下操作:

processID=`pgrep "processName"` 
kill $processID
startProcess.sh

该进程被杀死,然后在脚本startProcess.sh中启动,如下所示:

pidof "processName"

if [ ! $? -eq 0 ]; then
    nohup "processName" "processArgs" >> "processLog" &
    pidof "processName"
    if [! $? -eq 0]; then
        echo "Error: failed to start process"
...

update.sh,startprocess.sh及其启动的实际二进制文件位于从中央服务器装入的NFS上。

现在,有时发生的是,我尝试在startprocess.sh中启动的进程未启动,并且出现了错误。奇怪的是,它是随机的,有时一台计算机上的进程开始,而同一台计算机上的另一时间没有启动。我正在检查大约300台服务器,并且错误始终是随机的。

还有另一件事,远程服务器位于3个不同的地理位置(美国2个,欧洲1个),中央服务器在欧洲。我到目前为止发现的是,美国的服务器比欧洲的服务器有更多的错误。

首先,我认为该错误与kill有关系,因此我在kill和startprocess.sh之间添加了睡眠,但这没有任何区别。

同样,似乎startprocess.sh的进程根本没有启动,或者启动时发生了某些事情,因为日志文件中没有输出,并且日志文件中应该有输出。

所以,我在这里寻求帮助

是否有人遇到过此类问题,或者知道可能出什么问题了?

谢谢你的帮助

(对不起,但我最初的回答是错误的。。。这是更正)

使用$?来获取后台进程的退出状态startProcess.sh会导致错误的结果。男子状态:

Special Parameters
?      Expands to the status of the most recently executed foreground
       pipeline.

正如您在评论中提到的那样,获取后台进程退出状态的正确方法是使用wait内置函数。但是,为此必须处理SIGCHLD信号。

我为此做了一个小型测试环境,以展示其工作方式:

这是一个loop.sh作为后台进程运行的脚本

#!/bin/bash
[ "$1" == -x ] && exit 1;
cnt=${1:-500}
while ((++c<=cnt)); do echo "SLEEPING [$$]: $c/$cnt"; sleep 5; done

如果参数为arg,-x则它以退出状态1退出以模拟错误。如果arg为num,则等待num * 5秒打印SLEEPING [<PID>] <counter>/<max_counter>到stdout。

第二个是启动器脚本。loop.sh在后台启动3个脚本并显示其退出状态:

#!/bin/bash

handle_chld() {
    local tmp=()
    for i in ${!pids[@]}; do
        if [ ! -d /proc/${pids[i]} ]; then
            wait ${pids[i]}
            echo "Stopped ${pids[i]}; exit code: $?"
            unset pids[i]
        fi
    done
}

set -o monitor
trap "handle_chld" CHLD

# Start background processes
./loop.sh 3 &
pids+=($!)
./loop.sh 2 &
pids+=($!)
./loop.sh -x &
pids+=($!)

# Wait until all background processes are stopped
while [ ${#pids[@]} -gt 0 ]; do echo "WAITING FOR: ${pids[@]}"; sleep 2; done
echo STOPPED

handle_chld函数将处理SIGCHLD信号。设置选项monitor允许非交互式脚本接收SIGCHLD。然后将陷阱设置为SIGCHLD信号。

然后启动后台进程。它们的所有PID都记住在pids数组中。如果收到SIGCHLD,则在/ proc /目录中检查停止了哪个子进程(缺少的子进程)(也可以使用内置的kill -0 <PID> 进行检查)。等待之后,后台进程的退出状态存储在著名的$?伪变量中。

主脚本等待所有pid停止(否则它无法获取其子级的退出状态),并且它自身停止。

输出示例:

WAITING FOR: 13102 13103 13104
SLEEPING [13103]: 1/2
SLEEPING [13102]: 1/3
Stopped 13104; exit code: 1
WAITING FOR: 13102 13103
WAITING FOR: 13102 13103
SLEEPING [13103]: 2/2
SLEEPING [13102]: 2/3
WAITING FOR: 13102 13103
WAITING FOR: 13102 13103
SLEEPING [13102]: 3/3
Stopped 13103; exit code: 0
WAITING FOR: 13102
WAITING FOR: 13102
WAITING FOR: 13102
Stopped 13102; exit code: 0
STOPPED

可以看出,退出代码报告正确。

我希望这可以有所帮助!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Xcode:进程启动失败-安全

来自分类Dev

Bash脚本来监视进程和sendmail如果失败

来自分类Dev

检查从同一bash脚本启动的后台进程的运行状态

来自分类Dev

从python脚本中启动并行进程?

来自分类Dev

进程启动失败:无法获得进程2847的任务

来自分类Dev

如何检查启动后台进程的bash脚本的执行时间

来自分类Dev

使用CTRL-C终止由bash脚本启动的进程

来自分类Dev

从人偶执行bash脚本失败

来自分类Dev

Bash脚本启动,然后关闭/重新启动各种进程

来自分类Dev

启动Python进程后如何退出bash脚本?

来自分类Dev

Alfred Workflow Bash脚本失败

来自分类Dev

npm:启动脚本失败

来自分类Dev

如何杀死启动新进程的脚本?

来自分类Dev

使用SSH(脚本,插件等)启动进程

来自分类Dev

挂起从脚本启动的ssh进程

来自分类Dev

Bash脚本启动,然后关闭/重新启动各种进程

来自分类Dev

检查从脚本并行启动的进程的退出代码

来自分类Dev

如何从PHP / bash脚本启动/结束后台进程?

来自分类Dev

启动Powershell进程并运行脚本

来自分类Dev

无法启动“ MyApplication”启动失败:进程启动失败:等待应用程序启动超时?

来自分类Dev

Tmux-如果使用bash启动脚本,则分离客户端失败

来自分类Dev

如何使用Ctrl + C杀死在Bash脚本中启动的所有后台进程?

来自分类Dev

进程检查失败时退出Shell脚本

来自分类Dev

如果死于脚本,如何启动Java进程

来自分类Dev

通过子进程运行Python脚本失败

来自分类Dev

杀死进程由bash脚本启动,但不是脚本本身

来自分类Dev

脚本启动循环中的进程的PID

来自分类Dev

Bash脚本启动“孤立”后台进程

来自分类Dev

Bash 脚本运行一个分离的循环,顺序启动后台进程

Related 相关文章

热门标签

归档