【问题标题】:Variable incrementing in bashbash中的变量递增
【发布时间】:2011-11-20 21:40:09
【问题描述】:

考虑以下脚本:

#!/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。

【问题讨论】:

  • 可能问题出在管道上。使用标准输入不显示问题:ideone.com/87yi6

标签: linux bash variables


【解决方案1】:

为什么?这是因为:

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

【讨论】:

    【解决方案2】:

    要添加到上一个答案:并避免这种情况(和 UUOC),您需要这样的东西:

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

    【讨论】:

      【解决方案3】:

      只需将所有变量保存在同一个环境中即可。在第 4 行,删除“cat 文件 |”。在第 9 行,附加“

      【讨论】:

        猜你喜欢
        • 2016-12-23
        • 2017-01-18
        • 2016-12-06
        • 1970-01-01
        • 1970-01-01
        • 2013-02-20
        • 1970-01-01
        • 2014-01-07
        • 1970-01-01
        相关资源
        最近更新 更多