好奇的问题:针对''vs.读取循环和shell脚本中变量的可见性 [英] curious problem: for `` vs. while-read loops and visibility of variables in shell scripts

查看:147
本文介绍了好奇的问题:针对''vs.读取循环和shell脚本中变量的可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在从while循环内部更新shell脚本中变量的值时遇到问题.可以使用以下代码来模拟它:

I have a problem updating a value of a variable in a shell script from inside of a while loop. It can be simulated with the following piece of code:


 printf "aaa\nbbb\n" | \
      while read x ; do
          y=$x
          echo "INSIDE: $y"
      done
 echo "OUTSIDE: $y"

输出:


INSIDE: aaa
INSIDE: bbb
OUTSIDE: 

这里的printf命令仅显示两行,而read循环则逐行读取它,更新某些变量,但是一旦控件退出循环,变量的值就会丢失.

Here printf command just display two lines, while-read loop read it line by line, updating certain variable, but as soon as control going out of the loop the value of the variable gets lost.

我想这个问题与以下事实有关:读取时发出管道"语句导致shell在子进程中执行循环的主体,而子进程无法更新主循环中的shell变量.

I guess the problem is related to the fact that 'pipe-while-read' statement causes shell to execute the body of the loop in a subprocess, which cannot update the shell variables in the main loop.

如果我将前两行代码重写为

If I rewrite the first two lines of code as


 for x in `printf "aaa\nbbb\n" ` ; do

输出:


INSIDE: aaa
INSIDE: bbb
OUTSIDE: bbb

这可能是一种解决方法,但不适用于我的情况,因为实际上我没有'aaa'和'bbb'而是更复杂的字符串,包括空格等.

It could be a workaround, but not for my case because in reality I have not 'aaa' and 'bbb' but more complex strings including whitespaces etc.

有什么想法可以解决该问题,即:在循环中逐行读取命令输出并能够更新shell变量?

Any idea how to tackle the problem, namely: read a command output line by line in a loop and be able to update shell variables?

谢谢.

推荐答案

man bash的摘录:

管道中的每个命令都作为一个单独的进程(即在子shell中)执行.

Each command in a pipeline is executed as a separate process (i.e., in a subshell).

并且Subshel​​l无法更改Parent中的变量.

And Subshell cannot change the variable in Parent.

可能的解决方案之一是:

One of the possible Solution is:

IFS='\n'
while read x ; do
   y=${x}
   echo "INSIDE: ${y}"
done <<EOT
aaa
bbb
EOT
echo "OUTSIDE: ${y}"

或者如果输入是文件:

IFS='\n'
while read x ; do
   y=${x}
   echo "INSIDE: ${y}"
done < /path/to/file
echo "OUTSIDE: ${y}"

这一次读取一行,并且空格没有任何问题.

This reads one line at a time, and doesn't have any issue with spaces.

这篇关于好奇的问题:针对''vs.读取循环和shell脚本中变量的可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆