在shell脚本中,for循环中的'if-else'是如何执行的?为什么它只为变量打印一次?

时间:2015-12-16 13:15:40

标签: linux bash shell if-statement for-loop

我写了一个shell片段,如下所示:

is_first=t
for f in "$path"/"m*"
do
    printf "%s\n" $f
    printf "%s\n" $is_first

    if [[ "$is_first" = "t" ]]; then
        is_first=f
        printf "%s\n" $is_first
    else
        printf "%s\n" $is_first
    fi

    printf "%s\n" $is_first
done

输出如下:

./merge_non-null
./merge_non-null_bak.sh
./merge_non-null.sh
t
f
f

我想知道, if-else如何在for循环中执行?它似乎只针对第一个循环运行,之后都跳过了。

另外,为什么printf "%s\n" $is_first仅针对第一个循环执行? 我期望的输出是(注意序列)。我相信我错过了什么。对不起,如果它太愚蠢了。

./merge_non-null
t
f
f
./merge_non-null_bak.sh
f
f
f
./merge_non-null.sh
f
f
f

1 个答案:

答案 0 :(得分:6)

您的报价不正确。 "m*"没有扩展,因为它是双引号,所以你循环文字字符串;所以循环只执行一次。然后你在循环中错误地省略引号,因此shell将参数中的通配符扩展为第一个printf。如果没有引号,带有此格式字符串的printf会在展开的字符串中为每个标记打印一行;所以你从循环的单个迭代中获得多个输出行,从第一个printf开始。

正确引用后,您的脚本将变为

is_first=t
for f in "$path/m"*
do
    printf "%s\n" "$f"
    printf "%s\n" "$is_first"

    if [[ "$is_first" = "t" ]]; then
        is_first=f
        printf "%s\n" "$is_first"
    else
        printf "%s\n" "$is_first"
    fi

    printf "%s\n" "$is_first"
done

另见When to wrap quotes around a shell variable?