我正在AIX 5.3中编写一个脚本,它将通过df的输出循环,并检查每个卷与另一个configuration文件。 如果卷出现在configuration文件中,它将设置稍后在脚本中需要的标志。 如果我的configuration文件只有一个列,我使用for循环,这完美的作品。 然而,我的问题是,如果我使用一个while read循环来为每行填充多个variables,那么while和done之间设置的任何variables都将被丢弃。
例如,假设/netapp/conf/ExcludeFile.conf的内容是一堆包含两个字段的行:
volName="myVolume" utilization=70 thresholdFlag=0 grep volName /netapp/conf/ExcludeFile.conf | while read vol threshold; do if [ $utilization -ge $threshold ] ; then thresholdFlag=1 fi done echo "$thresholdFlag"
在此示例中,即使卷出现在文件中并且其利用率大于阈值,thresholdFlag也将始终为0。 我可以在那里添加一个echo "setting thresholdFlag to 1" ,看到回声,最后还是会回显0。
有没有一个干净的方法来做到这一点? 我认为我的while循环是在一个子shell中完成的,而且我对variables的修改实际上是在done之后丢弃的局部variables。
Zoredache在聊天中指出了这一点,并且在他的回答中提到了这个问题:这个问题可以通过一个子shell来解决。
当我不得不从一个从我的grep读取单个variables的for循环更换一段时间while read var1 var2循环,这让我可以读取多个variables,我能够挂在我操作的临时variables循环使用括号来定义一个显式的子shell。 这是一个例子:
sum=0 grep volume configfile | head -n1 | (while read var1 var2; do let sum=var1+var2 done echo "The sum is $sum.")
如果没有括号,总会回显总和为0.对于它们,您将在您的grep的第一个匹配行中回显前两个值的总和。
此外,正如Poige在另一个答案中指出的那样,您可以使用subshell来填充一个范围内的variables,如下所示:
var=$( cat file | while read ab; do sum=a+b echo "$sum" done) echo "$var"
在这种情况下,最后回显的var的值将是您在循环中计算的最后一笔总和,即使sum在子shell的末尾被销毁。
至less有两种方法 – 返回Err代码并检查它,或者包装你的子shell代码:
Res=$(cat /etc/hosts | while read h _rest; do [ "$h" = 'fe00::0' ] && echo 'Found' done ) echo $Res