繁体   English   中英

bash中的变量递增

[英]Variable incrementing in bash

请考虑以下脚本:

#!/bin/bash

num=0
cat file | while read line; do
    echo "$line"
    lines[$num]="$line"
    ((num++))
    echo "num = $num"
done

echo "end num = $num"

i=0
while [ $i -lt $num ]; do
    echo "${lines[$i]}"
    ((i++))
done

通常,它应该逐行读取文件,将结果存储在一个数组中,然后通过数组并逐行打印。 问题是变量$ num在第一个循环退出后以某种方式重置。 这个脚本的输出对我来说是(使用带有一些随机垃圾的文件):

dsfkljhhsdfsdfshdjkfgd
num = 1
fdfgdfgdfg
num = 2
dfgdfgdfgdfg
num = 3
dfgdfgdfgdfgdfg
num = 4
dfgdfgdfgdfgdfgd
num = 5
fgdfgdfgdfg
num = 6
dfgdfgdfgdfg
num = 7
dfgdfgdfgdfgdfg
num = 8
dfgdfgdfgdfg
num = 9
dfgdfgdgdgdg
num = 10
dfgdffgdgdgdg
num = 11
end num = 0

为什么是这样? 如何记住变量? 我在SUSE Linux 10上使用bash 3.1.17。

为什么? 这是因为:

cat file | while read line; do
    echo "$line"
    lines[$num]="$line"
    ((num++))
    echo "num = $num"
done

在单独的进程中运行while语句,具有自己的环境,而不是触及父环境。 同样地,你会发现lines数组也不存在。

以下简化脚本显示了此操作:

#!/bin/bash
export xyzzy=42
echo urk | while read line; do
    xyzzy=999
    echo $xyzzy
done
echo $xyzzy

该脚本的输出是:

999
42

因为变量设置为999是在子进程中完成的。

最重要的是,如果您希望信息反映在当前流程(脚本)中,您需要脚本中完成工作或找到其他方法从子流程中获取信息。

如果您使用输入重定向而不是启动子流程管道,它应该可以按您的意愿工作。 这是因为while位然后在当前进程的上下文中完成,而不是在管道中的单独进程。 例如:

#!/bin/bash
export xyzzy=42
while read line; do
    xyzzy=999
    echo $xyzzy
done <<EOF
hello
EOF
echo $xyzzy

将产生:

999
999

对于您的具体情况,请替换:

done <<EOF
hello
EOF

有:

done <file

要添加到上一个答案:并且为了避免(和UUOC),你需要这样的东西:

while ...; do
  ...
done < file

只需将变量保存在同一环境中即可。 在第4行,删除“cat file |”。 在第9行,追加“<file”。 你的结束数现在将包含预期的11,而lines数组将通过你的第二个循环一次打印一个元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM