想请教各位 v2 shell 脚本比较精通的,被这个问题卡住了. - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
freaks
1.01D
V2EX    Linux

想请教各位 v2 shell 脚本比较精通的,被这个问题卡住了.

  •  
  •   freaks 2022-04-16 08:42:12 +08:00 via iPhone 5417 次点击
    这是一个创建于 1348 天前的主题,其中的信息可能已经有所发展或是发生改变。
    自己写了个检测宽带公网出口 ip 变化的脚本,并通过企微的群聊机器人通知,想放到后台一直运行,但都是运行了:
    nohup sh scriptName.sh > /dev/null 2>&1 & 后 使用 ps - ef | grep scriptName.sh 后显示了一次,在此运行命令就看不到运行了。我用 bash -x script Name.sh 可以运行成功,也可以发起通知,但就是放不到后台执行,不知道哪里出问题了,还请各位大神不吝赐教,小弟在此谢过了. 搜了好多文章也没找到问题原因,要了.
    34 条回复    2022-04-19 10:06:31 +08:00
    Tink
        1
    Tink  
    PRO
       2022-04-16 08:49:09 +08:00 via Android   1
    你这个脚本里面实现了一直循环?如果没有的话要用 cron
    DCCooper
        2
    DCCooper  
       2022-04-16 08:50:54 +08:00 via iPhone
    脚本退出了
    liangkang1436
        3
    liangkang1436  
       2022-04-16 09:10:40 +08:00 via Android
    @DCCooper 你要不做成服务算了,启动,停止都方便些
    plko345
        4
    plko345  
       2022-04-16 09:14:09 +08:00 via Android
    那你把结果重定向到文本里呀,可能脚本不健壮,某次失败退出了,你全都指向 null ,有问题也发现不了
    zhouzm
        5
    zhouzm  
       2022-04-16 09:18:28 +08:00
    # check-gateway.sh
    #! /bin/bash

    [[ ! -z "$1" ]] && host=$1 || host=192.168.1.1

    c=0
    last=0
    # while [[ $c -lt 100 ]]; do
    while true; do
    ping -q -c 1 -W 1 $host >/dev/null
    current=$?
    if [[ $current == 0 ]]; then
    if [[ $last != 0 || $c -eq 0 ]]; then
    last=$current
    echo $( date +%Y-%m-%d\|%H:%M:%S ) :$host online >> /run/check-gateway.log
    fi
    else
    if [[ $last == 0 ]]; then
    last=$current
    echo $( date +%Y-%m-%d\|%H:%M:%S ) :$host offline >> /run/check-gateway.log
    fi
    fi
    c=$(( $c + 1 ))
    sleep 1
    done
    exit 0



    nohup check-gateway.sh $IP >/dev/null 2>&1 &
    ch2
        6
    ch2  
       2022-04-16 09:19:21 +08:00 via iPhone
    有两个选择:
    1. 用 crontab 做成定时任务,每分钟检测一次,每次只跑完就退
    2.用 systemctl 做成服务,常驻后台
    lcy630409
        7
    lcy630409  
       2022-04-16 09:48:58 +08:00
    这个最简单的就是 crontab 了,定时执行即可
    freaks
        8
    freaks  
    OP
       2022-04-16 12:12:45 +08:00 via iPhone
    @Tink 就是写了个函数 if 判断下,和随便伪造的一个 IP 比对下,如果不同,就调用函数发到群聊里,相同就把信息输出到一个文本文件,然后不发告警.
    freaks
        9
    freaks  
    OP
       2022-04-16 12:13:26 +08:00 via iPhone
    @DCCooper 即没返回 127 也没返回 128
    freaks
        10
    freaks  
    OP
       2022-04-16 12:14:14 +08:00 via iPhone
    @liangkang1436 感觉像运行一次就结束了,达不到实时监控的目的
    freaks
        11
    freaks  
    OP
       2022-04-16 12:15:08 +08:00 via iPhone
    @plko345 我不指向空,也是默认追加到 nohup.out 没有报错的
    freaks
        12
    freaks  
    OP
       2022-04-16 12:17:20 +08:00 via iPhone
    @zhouzm 这个脚本是检测网关的吗?我是要检测出口公网 IP 隔一段时间改变,作提醒,还是感谢回答,我再研究研究
    freaks
        13
    freaks  
    OP
       2022-04-16 12:20:22 +08:00 via iPhone
    @ch2 有考虑过这样,但总感觉这个问题很简单,但自己又实在想知道原因,定时任务每分钟运行,可能造成日志过大,如果把周期拉长,可能会有探测不到变化的情况,不知道理解对不对.
    freaks
        14
    freaks  
    OP
       2022-04-16 12:21:09 +08:00 via iPhone
    @lcy630409 实在没招了,会考虑,不过现在确实卡住了
    Tink
        15
    Tink  
    PRO
       2022-04-16 12:32:18 +08:00 via Android
    @freaks 按你的意思,你的脚本里面本身就是只执行一次啊,要么你就外面套一个死循环,要么就用 cron 定时一分钟运行一次
    freaks
        16
    freaks  
    OP
       2022-04-16 12:34:59 +08:00 via iPhone
    #!/bin/bash

    #存放变化 IP 的文件

    dirfile="/home/ip_change"

    # 获取 IP

    IP=`curl -s ip.sb`

    log="/var/log/tool.log"

    datetime=`date '+%Y-%m-%d %H:%M:%S'`

    if [ ! -f "$dirfile" ]; then
    touch "$dirfile"
    echo "1.1.1.1">$dirfile
    fi


    # 判断公网 IP 是否获取

    if [ ! -n "$IP" ]; then
    echo "$datetime 公网 IP 获取失败,检查'curl -s ip.sb'">> $log
    exit 1
    fi

    # 查看老 ip

    old_ip=`cat $dirfile`


    # 调用微信群聊机器人接口

    wx_web(){
    cat > sendweb.sh << EOF
    curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=' \
    -H 'Content-Type: application/json' -d \
    '{ \
    "msgtype": "text", \
    "text": { \
    "content": "公司外网发生了变化 新的 IP: ${IP} 老的 IP: ${old_ip} !!!" \
    } \
    }'
    EOF
    chmod +x sendweb.sh
    sh sendweb.sh && rm -rf sendweb.sh
    }

    if [ "$IP" = "$old_ip" ]; then
    echo "$datetime IP 正常 - true " >> $log
    else
    echo $IP > $dirfile
    wx_web
    fi
    freaks
        17
    freaks  
    OP
       2022-04-16 12:35:54 +08:00 via iPhone
    @Tink 下面放了脚本,希望大佬帮忙看看
    yaoyaomoe
        18
    yaoyaomoe  
       2022-04-16 12:38:57 +08:00 via iPhone
    没 loop……
    MilkShake
        19
    MilkShake  
       2022-04-16 12:48:26 +08:00
    可以 while 死循环脚本,丢到后台运行。或者用计划任务。
    freaks
        20
    freaks  
    OP
       2022-04-16 12:50:29 +08:00 via iPhone
    @aaa5838769 好吧,还是代码的问题,这个是不是在 if 那里加就行了?
    felixcode
        21
    felixcode  
       2022-04-16 13:59:11 +08:00
    用 cronjob 或 systemd 做吧,还能看看执行日志,nohup 太山寨了
    itechify
        22
    itechify  
    PRO
       2022-04-16 14:04:04 +08:00 via Android
    在 cron 定时知道就行了
    Cbdy
        23
    Cbdy  
       2022-04-16 14:29:25 +08:00 via Android
    可以用 pm2
    pengtdyd
        24
    pengtdyd  
       2022-04-16 14:51:31 +08:00
    我就是脚本小王子,哈哈哈哈。盲猜 99%是因为脚本里面报错,所以进程退出了。
    freaks
        25
    freaks  
    OP
       2022-04-16 15:02:06 +08:00 via iPhone
    @oneisall8955 已经使用定时任务替代,用 systemd 可以不加 while 一直运行吗
    zhouzm
        26
    zhouzm  
       2022-04-16 15:26:49 +08:00
    你的脚本是在 linux 下运行还是在 openwrt 下运行?
    zhouzm
        27
    zhouzm  
       2022-04-16 15:39:22 +08:00   1
    上面有人说 nohup 太山寨这种说法是不妥的,cron 只支持最小 1 分钟的间隔频率,如果对监控结果实时性敏感度高的话,用脚本循环判断是比较简便的方案。

    @freaks 我上面给的脚本是我一直在用的,用途是判断网关是否在线,是完整的循环处理代码,你只需要把 while 循环内代码替换成你的检测脚本就可以了。
    手动运行测试的时候可以把 while true; do 注释掉,使用上面一行,100 是你想测试循环的次数,测试不报错后再改成一直循环,然后 nohup check-gateway.sh $IP >/dev/null 2>&1 & 运行就可以了。

    bash 的 sleep 是不消耗 cpu 的,可以放心大胆的使用。
    freaks
        28
    freaks  
    OP
       2022-04-16 16:20:31 +08:00 via iPhone
    @zhouzm 非常感谢提供思路,我这里就是 Linux 系统下,这东西存在就有意义,不然不早被拿掉了,说山寨未免太那个了。我抽空试试你的方法,现在先 crontab 一段时间.
    Cu635
        29
    Cu635  
       2022-04-16 16:25:18 +08:00
    @zhouzm
    @freaks
    说 nohup 山寨是因为有了更好用的 screen 吧……
    huntagain2008
        30
    huntagain2008  
       2022-04-16 16:31:41 +08:00
    新手昨天刚看到 1983 年 unix 编程环境 5.3while 和 until
    $cat watch who
    ...
    while : # coop forever
    do
    who>$new
    diff $new $old
    sleep 60
    done
    ...
    $
    :是 shell 内部命令,它仅仅计算参数值,然后返回“真”。while 循环体,只要命令返回状态为真便继续执行。还可以自定义时间间隔
    $cat check mail
    ...
    t=$(1-60)
    ...
    $
    时间间隔依然设为 60 秒,但在命令行提供了一个参数,如果键入下面命令
    $ checkmail 30
    就使用新的时间参数。如果提供了时间参数,shell 变量 t 被设为对应的时间间隔,如果未提供,缺省时间间隔为 60 秒
    felixcode
        31
    felixcode  
       2022-04-16 16:50:32 +08:00
    说 nohup 山寨是因为缺乏基本的监测控制。
    这个程序是作为监测服务运行的,如果 nohup 进程挂了,不会自动重启,也不会有任何通知,而管理员是完全不知道的。
    用 systemd 就能避免这样的情况,cron 的话可以不在意前面的运行是否成功。
    baobao1270
        32
    baobao1270  
       2022-04-17 06:33:22 +08:00   1
    上面说用 systemd 做成 service 的都是什么人啊
    systemd 的正确用法是做成 timer
    felixcode
        33
    felixcode  
       2022-04-17 12:13:36 +08:00 via Android
    @baobao1270 既能用 timer 也能用来控制循环脚本啊,用法又不唯一
    hcql
        34
    hcql  
       2022-04-19 10:06:31 +08:00
    可以使用这种

    #!/bin/sh
    while true; do
    "checkyouripcommad"
    done
    sleep 60
    done
    关于     帮助文档     自助推广系统    博客     API     FAQ     Solana     929 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 20:30 PVG 04:30 LAX 12:30 JFK 15:30
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86