简体   繁体   English

修改循环变量bash

[英]Modify loop variable bash

I want to be able to modify the value of the variable used in a for-in loop, from inside the loop. 我希望能够从循环内部修改for-in循环中使用的变量的值。

Consider the following code: 考虑以下代码:

#!/bin/bash
for i in {1..100} 
do 
    ((i--))
done;

Why is this loop not an infinite-loop? 为什么这个循环不是无限循环? How can it be so? 怎么会这样

Because it is not a C-style loop. 因为它不是C风格的循环。 The condition to exit the loop is not anyhow related to the value of i . 退出循环的条件与i的值无关。 It will just loop over the range from 1 to 100 and that's about it. 它只会在1到100的范围内循环,仅此而已。

You can use C-style for-loop in bash if you have to: 如果需要,可以在bash中使用C样式的for循环:

for ((i=1; x<=100; i++)); do
    ((i--))
done

The for in loop in shell is not numeric, instead it works on a list of strings that is generated from the next token/construct after in and stored in memory. Shell中的for in循环不是数字的,而是作用于in之后的下一个标记/构造所生成并存储在内存中的字符串列表。 The indicated [control] variable takes the values from the list, one after another in each iteration; 指示的[control]变量从列表中获取值,每次迭代都一个接一个地进行; there is no way to manipulate that list. 无法操纵该列表。 You can modify the variable inside the loop, ok, but at the next iteration it will get the next value of the list. 您可以在循环内修改变量,确定,但是在下一次迭代时,它将获得列表的下一个值。

In other words, the control variable is not a control variable, it's only a placeholder to refer to the current items of the list (better: it does not "refer", it contains a copy of the referred item). 换句话说,控制变量不是 控制变量,它只是引用列表中当前项目的占位符(更好:它不是“ refer”,它包含所引用项目的副本 )。

This means that the number of iterations is predetermined once, when the list of string is created. 这意味着在创建字符串列表时,迭代次数将预先确定一次。 The number of iterations is equal to the number of strings in the list (of course you can break inside the loop). 迭代次数等于列表中的字符串数(当然,您可以在循环内中断 )。

Other languages have similar constructs, like for each ... , or using iterators and so on. 其他语言也有类似的构造,例如for each ...或使用迭代器等。

The real thing about for can be explained with the following example: 可以通过以下示例解释有关for的真实情况:

for a in *
do echo $a
done

is really interpreted as 真的被解释为

for a in file1 file2 file3 file4 ie all the files in current directory
....

as is in fact perfectly legal to write 实际上是完全合法的

for a in 1 2 3 4 A B C D
...

Last note. 最后一点。 I said the list of a for is kept in memory. 我说过for的列表保存在内存中。 I opened two terminals, launched a for in one, at checked the memory consumption in the other using free(1). 我打开两个端子,展开了for在一个,在检查中使用的其它的存储器消耗自由(1)。

for a in 1 2 3; do sleep 50; done
...gives...
             total       used       free     shared    buffers     cached
Mem:        246596     224712      21884          0      33948      71584


for a in $(seq 1 1000000); do sleep 50; done
...gives...
             total       used       free     shared    buffers     cached
Mem:        246596     242864       3732          0       8400      24668

(notice the drop of buffers from 33948 to 8400, and the cached from 71584 to 24668). (请注意,缓冲区从33948下降到8400,缓存从71584下降到24668)。 Finally ask for ten times more: 最后再要求十倍:

for a in $(seq 1 10000000); do sleep 50; done
...gives...
             total       used       free     shared    buffers     cached
Mem:        246596     243492       3104          0        688       8700

(more drop of buffers). (更多的缓冲区下降)。 The kernel is trying to find more memory and, doing that, slows down the poor little computer! 内核试图寻找更多的内存,并且这样做会降低可怜的小型计算机的速度!

This shell for is very nice and powerful, but beware of the length of the list. 这个shell for很漂亮,功能强大,但列表的长度要小心了。

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

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