加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用system(3)运行bash脚本未收到信号

发布时间:2020-12-15 22:36:09 所属栏目:安全 来源:网络整理
导读:我有一个bash脚本,在发出守护进程信号之前等待3分钟. 在这3分钟内,如果收到SIGINT,我需要退出. 我的当前脚本在从bash运行时工作,但是,当我使用system()调用从另一个(C)程序中运行它时,它在发送SIGINT时不会退出. 这是我当前的脚本: #!/bin/bashtrap 'exit'
我有一个bash脚本,在发出守护进程信号之前等待3分钟.
在这3分钟内,如果收到SIGINT,我需要退出.

我的当前脚本在从bash运行时工作,但是,当我使用system()调用从另一个(C)程序中运行它时,它在发送SIGINT时不会退出.

这是我当前的脚本:

#!/bin/bash

trap 'exit' INT
sleep 180 &
wait
trap '' INT

/etc/init.d/myd sync

这是我运行它的方式:

kill -INT `pgrep myscript.sh` 2>/dev/null; ! pgrep -x "myscript.sh" > /dev/null && /opt/my/scripts/myscript.sh &

使用system()调用运行时,同一个衬管不起作用.

PS:
基本上,如果在3分钟内多次调用/etc/init.d/myd sync命令,它只在最后一次调用后运行它.

编辑1

要求的C代码:

system("kill -INT `pgrep myscript.sh` 2>/dev/null; ! pgrep -x "myscript.sh" > /dev/null && /opt/my/scripts/myscript.sh &");

C程序非常庞大(跨越数十个文件),所以我只是在这里粘贴特定的调用.该程序应该作为守护进程运行,但即使我不将其作为守护进程运行(使用命令行开关),我也会遇到此问题.

我可以使用以下简单的C代码重现这一点:

#include <stdlib.h>

int main(int argc,char *argv[]) {
    system("kill -INT `pgrep myscript.sh` 2>/dev/null; ! pgrep -x "myscript.sh" > /dev/null && /opt/my/scripts/myscript.sh &");        
    return 0;
}

解决方法

为什么(更新):

>实际的进程名称是bash,而不是myscript.sh
> pgrep可以在system()调用中通过sh匹配自己
>当脚本在后台运行时,SIGINT不会很好用. (已使用SIGUSR1代替)

经过对各种操作系统的一些讨论和测试,一旦淘汰了细微之处,这真的归结为:

>从tty启动脚本时,ps会显示:

46694 s001  S+     0:00.01 /bin/bash /opt/my/scripts/myscript.sh

>从system()调用(通过sh)启动脚本时,ps会显示:

46796 s002  S      0:00.00 /bin/bash /opt/my/scripts/myscript.sh

从ps手册:

>

  • 06002

所以没有它的进程没有使用SIGINT.

事实证明我们可以捕获SIGUSR1而发送它杀死-USR1

在Ubuntu 16.04和&amp ;;上进行工作测试Mac OS X 10.12:

cmon.c

>

#include 
int main(int argc,char *argv[]) {
system("mypid=`cat /opt/my/scripts/myscript.pid` ; ps -p $mypid > /dev/null && kill -USR1 $mypid 2>/dev/null ; mypid=`cat /opt/my/scripts/myscript.pid` ; ps -p $mypid > /dev/null || /opt/my/scripts/myscript.sh &");
return 0;
}

/opt/my/scripts/myscript.sh

>

#!/bin/bash
#process for this instance of bash bashpid="$$"

#ensure single instance mypid="$(cat "$(dirname "$0")/myscript.pid" 2>/dev/null)" ps -p $mypid &> /dev/null && (echo "already running,now going to exit this instance" ; echo "seems we never see this message,that's good,means the system() call is only spawning a new instance if there's no process match." ; kill -9 "$bashpid")

#set pidfile for this instance echo "$bashpid" > "$(dirname "$0")/myscript.pid"
trap 'echo "BYE" ; exit' SIGUSR1 sleep 5 & # 30 seconds for testing wait trap '' SIGUSR1
echo "Sitting here in limbo land" & while true ; do sleep 5 ; done

测试

简单的循环来循环./cmon二进制文件并检查我们每次都获得一个不同的进程(在超时窗口内):

unset i ; until [[ i -eq 5 ]] ; do ./cmon ; ps ax | grep bash.*myscript.sh | grep -v grep | awk -F ' ' '{print $1 " " $6}' ; sleep 1 ; (( i ++ )) ; done

超时到期后可以运行相同的行,以检查所有进程号是否相同

可在此处找到可粘贴的完整单元测试构建和测试序列:
ybin link

并在此处运行它的演示:

enter image description here

关于流程的说明:

>仅为了便于测试(即10秒超时窗口)修改脚本.
>冗余添加单实例检查(myscript.sh文件中的单实例触发器永远不应该被触发……似乎永远不会被触发)

OP确认最终工作时更新

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读