问题
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:
- Each process connected by a pipe
|
is a child of the current shell. - 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