简体   繁体   English

如何将正常的args和数组都传递给bash脚本参数?

[英]How can I pass normal args and array both to the bash script arguments?

I am trying to have a bash script that has some args. 我想要一个有一些args的bash脚本。 One of them needs to be an array so the number of args is not fixed in that array. 其中一个需要是一个数组,因此args的数量在该数组中不固定。

So I want to run my bash script as follows: 所以我想按如下方式运行我的bash脚本:

test.sh arg1 arg2 arr1

Inside test.sh, I'm doing something like 在test.sh里面,我正在做类似的事情

arg1=$1
arg2=$2

arr=$3 # arr1
for var in len(arr)
do
 # do something
done
#!/bin/bash

arg1=$1
arg2=$2

shift 2

for argn do
    # do something with "$argn"
done

That is, receive the two fixed arguments first, then shift these off the list of positional argument using shift 2 . 也就是说,首先接收两个固定的参数,然后使用shift 2将它们从位置参数列表中shift 2 What's left in the list of positional arguments is the variable length list of other arguments. 位置参数列表中剩下的是其他参数的可变长度列表。

That last loop can be written 可以写出最后一个循环

for argn in "$@"; do
    # do something with "$argn"
done

... but make sure that you use "$@" and not just $@ as that would split the individual arguments on whitespaces and invoke filename globbing. ...但请确保使用"$@"而不仅仅是$@因为这会将空格上的各个参数拆分并调用文件名通配符。

Your method of passing to the script is valid. 传递给脚本的方法是有效的。 You could rewrite your script as 您可以将脚本重写为

#!/bin/bash 
arg1=$1
arg2=$2
for i in $(seq 3 $#); do
     #reference each thing in arr1 with ${!i}
done

Though that's admittedly hard to read. 虽然这很难读懂。 {!var} is indirection (basically, you ask what for what i is equal to, and then you ask for whatever that is equal to, so if i=1 , you're doing ${!i} is the same as $1 ). {!var}是间接的(基本上,你问什么i等于,然后你问什么等于,所以如果i=1 ,你在做${!i}是一样的$1 )。

This doesn't keep the array together, though. 但是,这并不能将阵列保持在一起。 If you needed arr1 to stay arr1 in the script, you could do: 如果你需要arr1在脚本中保留arr1 ,你可以这样做:

#!/bin/bash 
arg1=$1
shift
arg2=$1
shift
arr1=("$@")

Bash takes command-line arguments by their position relative to the script name (which gets the variable $0 ). Bash通过相对于脚本名称(获取变量$0 )的位置获取命令行参数。 For your scenario, arg1 is $1 , arg2 is $2 , and arr1 is $3 $4 $5 ... , depending on the length of your array. 对于您的场景, arg1$1arg2$2arr1$3 $4 $5 ... ,具体取决于阵列的长度。 shift will move all the arguments down 1, making 1=$2 , 2=$3 , etc. for all the arguments you have. shift会将所有参数向下移动1,对于你拥有的所有参数,使得1=$2 2=$3等。 (It doesn't change $0 from the script name; that stays the same.) (它不会从脚本名称更改$0 ;它保持不变。)

$@ grabs ALL the command-line variables, starting at $1 . $@抓取所有命令行变量,从$1开始。 However, because we shifted away the variables for arg1 and arg2 , grabbing all the variables really means that we're only grabbing the variables that were originally part of our array. 但是,因为我们移走了arg1arg2 ,所以抓住所有变量实际上意味着我们只抓取最初属于数组的变量。

If you have multiple arrays, or the array is first in the list, then you have to know how many elements are in the array for it to work. 如果您有多个数组,或者数组是列表中的第一个数组,那么您必须知道数组中有多少元素才能工作。 Let's say you wanted to do test.sh arr1 var1 arr2 , and you knew both arrays were length 3: 假设你想做test.sh arr1 var1 arr2 ,你知道两个数组的长度都是3:

#!/bin/bash 
arr1=("${@:1:4}")
shift ${#arr1[@]} #shift by the length of arr1
arg1=$1
shift
arr2=("$@")

Hopefully you can see how this could work with a variable number of elements in the array, by passing the length of the array first, grabbing that with size=$(( 1 + $1 )) , then shift ing and grabbing the array with ${@:1:$size} and then doing ((size--)) and shift $size to start again with the next array size and array. 希望您可以通过首先传递数组的长度,使用size=$(( 1 + $1 )) ,然后使用${@:1:$size} shift并获取数组,来了解这对数组中可变数量的元素是如何工作的。 ${@:1:$size}然后执行((size--))shift $size以使用下一个数组大小和数组重新开始。

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

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