简体   繁体   中英

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. One of them needs to be an array so the number of args is not fixed in that array.

So I want to run my bash script as follows:

test.sh arg1 arg2 arr1

Inside test.sh, I'm doing something like

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 . 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 ).

This doesn't keep the array together, though. If you needed arr1 to stay arr1 in the script, you could do:

#!/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 ). For your scenario, arg1 is $1 , arg2 is $2 , and arr1 is $3 $4 $5 ... , depending on the length of your array. shift will move all the arguments down 1, making 1=$2 , 2=$3 , etc. for all the arguments you have. (It doesn't change $0 from the script name; that stays the same.)

$@ grabs ALL the command-line variables, starting at $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.

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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