zoukankan      html  css  js  c++  java
  • Shell进程间隔离与变量传递分析

    背景

    上回说到:
    Shell快速判断服务器是否在线以及占用情况(进程是否运行)

    这次进一步:
    希望对在线空闲的服务器执行一些操作。

    尝试

    容易想到构建一个数组保存空闲节点名称,随后遍历该数组发送指令。
    代码如下:

    #!/bin/bash
    echo Checking hosts...
    val=()
    for $host in Server-{{0..9},{A..Z}}
    do
    {
        if ping -w 3 $host > /dev/null
        then
            if [ `ssh user@$host pgrep -c myapp` -eq 0 ]
            then
                # The server is free
                val+=($host)
            fi
        fi
    }&
    done
    wait
    
    for host in ${val[*]}
    do
        ssh user@$host bash ~/work.sh
    done
    

    问题

    上述代码看似没毛病,可运行没反应。
    通过添加echo ${val[*]}打印变量发现数组val值为空!
    删去节点检测的&和wait改为顺序执行后val可以正常赋值?

    思考

    顺序检测36台服务器效率过低,方案否决!
    探究为何后台执行变量无法追加到val数组?
    难道shell变量也存在作用域?分全局和局部?

    查阅资料得:

    在 Shell 中定义的变量,默认就是全局变量。
    所谓全局变量,就是指变量在当前的整个 Shell 进程中都有效。
    每个 Shell 进程都有自己的作用域,彼此之间互不影响。

    比如,开启两个终端同时访问变量$a的值可以是不同的。
    for do {}& done wait结构下,后台产生了多个相互独立的进程同时执行,
    加速同时也隔离彼此变量传递,导致主进程变量val无法被赋值。

    解决

    既然如此,只需要聚合多进程的结果一起传入后续函数即可实现变量跨进程传递。
    这里将节点判断部分封装为一个函数,空闲节点名称直接打印到标准输出。
    再将函数输出作为输入构建循环列表,最终满足要求。

    修改后代码如下:

    #!/bin/bash
    echo Checking hosts...
    check(){
    for $host in Server-{{0..9},{A..Z}}
    do
    {
        if ping -w 3 $host > /dev/null
        then
            if [ `ssh user@$host pgrep -c myapp` -eq 0 ]
            then
                # The server is free
                echo $host
            fi
        fi
    }&
    done
    wait
    }
    
    for host in `check`
    do
        ssh user@$host bash ~/work.sh
    done
    
  • 相关阅读:
    梯度下降在实践I -特征缩放
    多变量的梯度下降
    多个变量的线性回归
    线性回归的梯度下降
    梯度下降的直觉
    梯度下降
    洛谷P1087--FBI树(二叉树)
    二叉树入门(洛谷P1305)
    二叉树--已知先序中序求后序--已知中序后序求先序(基本按照网上某大神思路搬过来的)
    多边形面积(计算几何)
  • 原文地址:https://www.cnblogs.com/azureology/p/13302155.html
Copyright © 2011-2022 走看看