Bash 在循环内设置全局变量并保留其值——或者过程替换虚拟变量
我是一名 C/C++ 程序员,总体来说相当愚蠢(或者至少 bash 做事的方式让我感到困惑)。我无法理解流程替换。
我需要定义一个全局布尔值,将其设置在循环中的某个位置,并在全局范围内使用它。有人可以用最简单的方式解释如何调整下面的代码以允许我实现我的用例,足够简单,这样我明天就不必再次扭曲我的大脑来尝试掌握流程替换。
# 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
老实说,我认为 bash 无法胜任这项任务......下一个块看起来像这样。
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 "-------------------------------------------------------------------------------"
我现在需要的是一个全局结构数组,以便我可以循环它们并采取条件操作来正确初始化我的守护进程:/。
可能只使用 libc 并在 lua 中执行此操作,我犹豫的唯一原因是必须安装岩石,我不喜欢临时代码存储库将他们想要的任何东西吐到我的机器上:D
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 ksh。它处理 | 的右侧不是作为子 shell,而是作为当前 shell。
x=1
x=3
ksh 可安装在 Ubuntu 中。
Use ksh. It processes the right side of | not as a subshell but a current shell.
x=1
x=3
ksh is installable in Ubuntu.
需要理解的重要一点是:子进程天生就有自己的环境,不能影响其父进程的变量。如果在子进程中设置变量,则父进程中的变量值不会受到影响。这实际上是两个不同的变量,只是碰巧具有相同的名称。
第二件需要理解的事情是 bash 何时作为子进程运行命令。有两种情况与该问题相关:
|
连接的每个进程都是当前 shell 的子进程。<
)不会生成子进程。下面是一个简单的会话,它演示了这些想法:
第一个
read
是一个子进程,因此主 shell 中的somevar
不会改变。第二个read
由主 shell 本身执行,因此somevar
被更新。这意味着您的代码将按您的预期工作,除非您在 for 循环之前或之后添加管道,即这将按您希望的方式工作:
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:
|
is a child of the current shell.<
) will not spawn a child process.Here is a simple session which demonstrates these ideas:
The first
read
is a child process and thereforesomevar
in the main shell does not change. The secondread
is executed by the main shell itself and hencesomevar
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:我可能误解了但是...
这是你想要的吗?
I might have misundestood but...
Is this what you want?