日期:2014-05-16  浏览次数:20720 次

【求助】Shell中变量赋值更新
代码如下:

tmp_file=test

idx=0 #idx第一次赋值
cat $tmp_file | while read line
do
  idx=$[$idx + 1]
  echo "idx:"$idx #更新,并赋值正常
done

echo "exit idx:"$idx #idx竟然还是为0


求助,上面代码最后一行,idx的取值竟然还是0.
它在while循环中已经被成功修改了啊?


------解决方案--------------------
管道另起一个进程,所以改的不是本脚本中的变量了。可以改为如下:

C/C++ code
tmp_file=1.txt

idx=0 #idx第一次赋值
exec 4<> $tmp_file
while read -u4 line 
do
    idx=$[$idx + 1]
     echo "idx:"$idx #更新,并赋值正常
 done

 echo "exit idx:"$idx #idx竟然还是为0

------解决方案--------------------
在bash下输入man exec,找到exec命令解释处,可以看到有”No new process is created.”这样的解释,这就是说exec命令不产生新的子进程。

系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。
------解决方案--------------------
exec 4<> $tmp_file
while read -u4 line

则会两句确实不明白?
------解决方案--------------------
exec是重定向用的,和linux C里的exec是不一样的。

exec 4>文件名 就是相当于linux c的int fd = open(文件, "w"); dup2(fd, 4); 。

这里read -u4就是从描述符4读数据的意思。

还有exec 4&-就是关闭描述符4, 是这么写吧。 

exec 4<文件名 是open("", "r"), <>当然就是r+了。

当然描述符之间也可以直接dup2, 比如exec 4>&1, 就是dup2(1, 4); 写4等于写标准输出。

注意,>往右是写,<是读,这只是SHELL得约定,实际从C语言实现角度看是毫无意义的。

对应的,exec 4<&0 就是dup2(0, 4), 读4等于读标准输入。