0

I am trying to pass an array of strings to my bash script that I want to iterate over. I want to set a default array in case the user does not provide this argument to the script.

This is what I have tried:

test.sh:

default_dirs=("x" "y")
dirs=("${1[@]:-${default_dirs[@]}}")
for directory in "${dirs[@]}"
do
    echo "$directory"
done

but running ./test.sh or

./test.sh "w" "z" yields:

./test.sh: line 2: ${1[@]:-${default_dirs[@]}}: bad substitution

What should I do differently?

3
  • (( ${#dirs[@]} )) || dirs=("${default_dirs[@]}") is one way. Commented Jun 26, 2020 at 10:54
  • dirs=("${dirs[@]:-"${default_dirs[@]}"}") might be what you wanted. Commented Jun 26, 2020 at 11:09
  • 1
    @cbakos : You can not pass arrays to child processes. Even ./test.sh w z invokes the script not with one array parameter, but with two parameters (w and z). It is just that inside the script, you can alternatively access all parameters passed via the special array named @. Note however, that @ does not behave in every respect like a bash array. Commented Jun 26, 2020 at 12:00

2 Answers 2

2

The arguments to the script don't all come in $1 (and $1 isn't an array which is why the substitution fails), so use $@ instead:

dirs=("${@:-${default_dirs[@]}}")
for directory in "${dirs[@]}"
do
    echo "$directory"
done
Sign up to request clarification or add additional context in comments.

Comments

0
files=(".env.test" ".env")

files_default=(".env.default")
files=("${files[@]:-${files_default[@]}}")

for key in "${files[@]}"; do
    echo "file: $key"
done

comment and uncomment first line and see the result with each...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.