Bash setting a global variable inside a loop and retaining its value — Or process substituion for dummies

梦想的初衷 提交于 2019-12-09 12:01:32

问题


I'm a C/C++ programmer and quite stupid in general (or at least the way bash does things it makes me feel confused). I can't wrap my head around process substitution.

I need to define a global boolean, set it somewhere in a loop, and make use of it in global scope. Could someone please explain in the simplest way possible how to adapt the code below to allow me to achieve my use case, simple enough so that I don't have to contort my brain again tomorrow to try and grasp process substitution .

# DEFINE HERE

for i in `seq 0 ${DAEMON_COUNT}`;
do
        if [ ! -d "data$i" ]; then
# SET HERE
                echo "data$i does not exist. Creating...";
                mkdir data$i
        fi
done

# TEST AND USE HERE

to be honest, I don't think bash is up to the task.... the next block looks like this.

echo "-------------------------------------------------------------------------------"
echo "checking the state of potentially running daemons"
for i in `seq 0 ${DAEMON_COUNT}`;
do
        if [ ! -e "data$i/mongod.lock" ] ; then
                echo "[no lock file] mongod process $i does not exist"
        else
                echo "[lock file exists] process $i lock file exists "
                I_PID=`cat data$i/mongod.lock`

                if [ ! ${I_PID} ]; then
                        echo "    [GOOD] lock pid empty"
                elif [ "`ps -p ${I_PID} | grep ${I_PID}`" ]; then
                        echo "    [GOOD] data1 pid: ${I_PID} running"
                else 
                        echo "[PROBABLY FATAL] data1 pid: ${I_PID} not running."
                fi 
        fi
done
echo "-------------------------------------------------------------------------------"

What I now need is a global array of structs so that I can loop over them and take conditional action to initialize my daemons correctly :/.

Might just use libc and do this stuff in lua, the only reason I hold back is having to install rocks, I don't like ad-hoc code repositories vomiting whatever they want onto my machine :D


回答1:


The important thing to understand is this: child process is born with its own environment and cannot affect the variables of its parent. If you set a variable in a child process, then the value of the variable in the parent is not affected. These are actually two different variables which just happen to have the same name.

The second thing to understand is when bash runs a command as a child process. There are two cases relevant to the question:

  1. Each process connected by a pipe | is a child of the current shell.
  2. Running a single builtin command with a redirection (e.g. <) will not spawn a child process.

Here is a simple session which demonstrates these ideas:

$ somevar=initial
$ echo test1 | read somevar
$ echo $somevar
initial
$ read somevar < <(echo test2)
$ echo $somevar
test2

The first read is a child process and therefore somevar in the main shell does not change. The second read is executed by the main shell itself and hence somevar is updated.

This means that your code will work as you expect unless you add a pipe in front of or after the for loop, i.e. this works as you want it to:

# DEFINE HERE
SOMEVAR=0
DAEMON_COUNT=10

for i in `seq 0 ${DAEMON_COUNT}`;
do
        if [ ! -d "data$i" ]; then
# SET HERE
                SOMEVAR=10
                echo "data$i does not exist. Creating...";
                mkdir data$i
        fi
done

# TEST AND USE HERE
echo ${SOMEVAR}     # This displays 10



回答2:


I might have misundestood but...

bool=false;

for i in `seq 0 ${DAEMON_COUNT}`;
do
    if [ ! -d "data$i" ]; then
            bool=true;
            echo "data$i does not exist. Creating...";
            mkdir data$i
    fi
done

if [ $bool = true ]; then 
    ... 
fi

Is this what you want?



来源:https://stackoverflow.com/questions/9012841/bash-setting-a-global-variable-inside-a-loop-and-retaining-its-value-or-proce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!