bash bash中函数参数和for循环的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3812385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:42:32  来源:igfitidea点击:

Problem with function arguments and for loop in bash

bash

提问by devoured elysium

Why doesn't this print all the passed arguments, in bash?

为什么这不在 bash 中打印所有传递的参数?

function abc() {
    echo "" #prints the correct argument

    for x in `seq 1 $#`; do
        echo "$x" #doesn't print the 1st, 2nd, etc arguments, but instead 1, 2, ..
    done
}

It is printing

它正在打印

1
2
3
4
...

instead.

反而。

回答by Gordon Davisson

I'll just add a couple more options to what everyone else has given. The closest to the way you're trying to write this is to use bash indirect expansion:

我只会在其他人给出的内容中添加更多选项。最接近您尝试编写此代码的方式是使用 bash 间接扩展:

function abc() {
    for x in `seq 1 $#`; do
        echo "${!x}"    # the ! adds a level of indirection
    done
}

...another option if you want to operate on only some of the arguments, is to use array slicing with $@:

...如果您只想对某些参数进行操作,另一种选择是使用 $@ 的数组切片:

function def() {
    for arg in "${@:2:3}"; do  # arguments 2 through 4 (i.e. 3 args starting at number 2)
        echo "$arg"
    done
}

similarly, "${@:2}"will give you all arguments starting at number 2, "${@:$start:$((end-start+1))}"will give you arguments $start through $end (the $((expression calculates how many arguments there are between $start and $end), etc...

同样,"${@:2}"会给你从数字 2 开始的所有参数,"${@:$start:$((end-start+1))}"会给你从 $start 到 $end 的参数($((表达式计算 $start 和 $end 之间有多少个参数),等等......

回答by DarkDust

The seqcommand returns all numbers from start to stop. What you are calling here is seq 1 <number_of_arguments_to_abc>. For example, if you call abc alpha beta gamma, then the arguments would be seq 1 3, thus you get the numbers 1, 2 and 3.

seq命令返回从开始到停止的所有数字。你在这里叫的是seq 1 <number_of_arguments_to_abc>. 例如,如果您调用abc alpha beta gamma,则参数将为seq 1 3,因此您会得到数字 1、2 和 3。

If you want the arguments to abc instead, the expression is for x in "$@".

如果您希望参数为 abc,则表达式为for x in "$@".

回答by jcubic

If you want to print all arguments try this

如果你想打印所有参数试试这个

function abc() {
   for arg in $@; do
      echo "$arg"
   done
}

回答by Chen Levy

Actually there is a special short-hand for this case:

其实这种情况有一个特殊的简写:

function abc() {
  for arg ; do
    echo "$arg"
  done
}

That is, if the in ...part is omitted, argloops over the function's argument $@.

也就是说,如果该in ...部分被省略,则arg循环遍历函数的参数$@

Incidentally if you have for arg ; ...outside of a function, it will iterate over the arguments given on the command line.

顺便说一句,如果您for arg ; ...在函数之外,它将迭代命令行上给出的参数。

回答by Paused until further notice.

You should use the for argform that others have shown. However, to address some things in your question and comments, see the following:

您应该使用for arg其他人展示的表格。但是,要解决您的问题和评论中的某些问题,请参阅以下内容:

In Bash, it's not necessary to use seq. You can use C-style forloops:

在 Bash 中,没有必要使用seq. 您可以使用 C 风格的for循环:

for ((i = 2; i <= $#; i++))
do
    echo "${@:i:1}"
done

Which demonstrates array slicing which is another technique you can use in addition to direct iteration (for arg) or using shift.

它演示了数组切片,这是除了直接迭代 ( for arg) 或使用shift.

An advantage of using either version of foris that the argument array is left intact, while shift modifies it. Also, with the C-style form with array slicing, you could skip any arguments you like. This is usually not done to the extent shown below, because it would rely on the arguments following a strict pattern.

使用任一版本的优点for是参数数组保持不变,而 shift 修改它。此外,使用带有数组切片的 C 样式形式,您可以跳过您喜欢的任何参数。这通常不会在下面显示的范围内完成,因为它会依赖于遵循严格模式的参数。

for ((i = 2; i < $# - 2; i+=2))

That bit of craziness would start at the second argument, process every other one and stop before the last two or three (depending on whether $#is odd or even).

那种疯狂会从第二个参数开始,每隔一个处理一个,并在最后两个或三个之前停止(取决于$#是奇数还是偶数)。

回答by Robert Wohlfarth

The variable Xholds the literal numbers. You're trying to do indirection- substitute $1where there's a $x. Indirection warps the brain. $@provides a simpler mechanism for looping over the arguments - without any adverse effects on your psyche.

变量X保存文字数字。您正在尝试进行间接访问-在有$x 的地方替换$1。间接扭曲大脑。$@提供了一种更简单的循环参数机制 - 不会对您的心理产生任何不利影响。

for x in "$@"; do
  echo $x
done

See the bash man pagefor more details on $@.

有关$@ 的更多详细信息,请参阅bash 手册页