我有一台中央服务器,在该服务器中,我定期从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之间添加了sleep,但这没有任何区别.

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

所以,我在这里寻求帮助

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

谢谢你的帮助

解决方法:

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

使用$?在startProcess.sh中获取后台进程的退出状态会导致错误的结果.男人bash指出:

Special Parameters

? Expands to the status of the most recently executed foreground

pipeline.

正如您在评论中提到的那样,获取后台进程退出状态的正确方法是使用内置的等待.但是,为此bash必须处理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>.到标准输出.

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

#!/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信号.通过设置选项监视器,可以使非交互式脚本接收SIGCHLD.然后将陷阱设置为SIGCHLD信号.

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

主脚本等待所有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

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

我希望这可以有所帮助!

标签:bash,linux,bash,bash,bash

来源: https://codeday.me/bug/20191029/1956947.html

linux脚本登录启动失败,linux-从bash脚本启动进程失败相关推荐

  1. linux脚本里用expect,如何在bash脚本中使用expect

    这是我在 following bash脚本中使用的代码片段: for user_input in `awk '{print}' testfile_$$.txt` do ipaddress=`echo ...

  2. aws linux 安装图形,linux – 用于安装AWS CLI工具的Bash脚本

    我正在编写一个自动安装和配置AWS CLI工具的bash脚本.我可以安装AWS CLI工具,但无法配置它. 我的脚本是这样的: #!/bin/bash wget https://s3.amazonaw ...

  3. linux 非登录shell自动,Linux 交互/非交互/登录/非登录 shell 的区别

    文章目录 一.交互shell 和 非交互shell 1.交互shell 2.非交互shell 3.区分方法 二.登录shell 和 非登录shell 1.登录shell 2.非登录shell 3.区分 ...

  4. linux 非登录shell自动,Linux登录shell和非登录(交互式shell)环境变量配置

    使用Jenkins执行shell脚本的时候, 碰到command not found. 比如java mvn, 这些环境变量配置在/etc/profile 中, 但jenkins执行的时候并没有加载. ...

  5. bash脚本创建变量_创建一个Bash脚本模板

    bash脚本创建变量 在本系列的第一篇文章中,您创建了一个很小的单行Bash脚本,并探讨了创建Shell脚本的原因,以及为什么它们是系统管理员而非编译程序最有效的选择. 在第二篇文章中,您将开始创建一 ...

  6. sh脚本和bash脚本_我是如何开始使用bash脚本的

    sh脚本和bash脚本 前几天我写了一个剧本. 对于某些人来说,这句话听起来没什么大不了的. 对于其他人,我知道您在外面,那句话很重要. 你看,我不是程序员. 我是作家 我需要解决的问题 我的问题很简 ...

  7. bash 获取脚本存放路径_如何获取Bash脚本自己的路径

    bash 获取脚本存放路径 Bash script may need to get its own path. In normal Bash script, $0 is the path to the ...

  8. sh脚本和bash脚本_使用此简单的Bash脚本在家打印双面文档

    sh脚本和bash脚本 我们家里有一台激光打印机. 惠普(Hewlett Packard)LaserJet Pro CP1525nw彩色打印机是一种较旧的型号,但它是一台出色的打印机,可以可靠地进行彩 ...

  9. Linux初级运维(七)——bash脚本编程(常见测试)

    一.bash中常用的条件测试 测试方法: [ expression ] [[expression]] test expression 1.整数测试 -gt:大于 -le:小于等于 -ne:不等于 -e ...

  10. linux里面的注释命令是啥,bash脚本中单行及多行注释方法

    一:单行注释直接在行首加"#" 如:#我是注释行 二.多行注释利用:空命令 注意:以下方法中如果在注释中出现反引号引用的命令将会执行,存在风险. 1.把输入重定义到前面的命令,但是 ...

最新文章

  1. 让英文版windows 8支持非Unicode程序的语言方法
  2. ASP.NET中新建Web网站并部署到IIS上(详细图文教程)
  3. jconsole命令(Java Monitoring and Management Console)
  4. servlet和jsp学习总结
  5. iOS12+Xcode 10 Error: Multiple commands producei
  6. 中国农业种植施肥机械行业市场供需与战略研究报告
  7. php-redis中文参考手册_zset
  8. 按名次对数据进行排序cpp_面试中的排序算法(Part 3)
  9. 并发编程常见面试题总结一
  10. 解析OA系统易用性的价值和意义
  11. Linux桌面没有minidwep,ubuntu 12.04完整安装minidwep-gtk教程
  12. c语言输出星号一行比一行星号少一个,c语言打印空白星号矩形
  13. caffe 损失函数
  14. linux系统工程师面试题答案整理
  15. 一、Blender的基础操作
  16. Easy Excel
  17. CATTI论坛上的励志文章
  18. MySQL 1075错误
  19. 利用代码审查元素解除百度云客户端限制方法
  20. Java字节流读取shp_SHN系列语音卡调试文档.doc

热门文章

  1. QT消息/事件循环机制与多线程的关系
  2. windows相关知识点分析
  3. c#使用System.Windows.Forms.DataVisualization.Charting.dll绘制图表实例
  4. MFC—对话框程序—模式对话框与非模式对话框
  5. C#操作配置文件中appSettings,connectionStrings节点
  6. php用mssql还是用pdo,php使用pdo连接mssql server数据库实例
  7. 第三次握手为什么没有序列号_图解TCP三次握手与四次分手
  8. excel趋势线公式导出_Java 添加、读取、删除Excel中的图表趋势线
  9. html5 摄像头拍摄视频教程,html5实现调用摄像头并拍照功能
  10. linux内核驱动开发 培训,嵌入式Linux驱动开发培训 - 华清远见教育集团官网