0

I am trying to store some function parameters in a bash array, but some of them are defined from the content of environment variables and they do not actually "expand" to their actual values (I hope to be clear enough):

Example:

fileprefix='20200222_*'
test=1
args=( '-F' )
[[ "${test}" == 1 ]] && args+=( '-la "${fileprefix}"' )

But when executing it it raises an error:

$ ls "${args[@]}"

ls: invalid option -- ' '
Try 'ls --help' for more information.

and:

$ echo "${args[@]}"

-F -la "${fileprefix}"

but:

$ echo "${fileprefix}"
20200222_*

I would expect:

$ ls "${args[@]}"

-rw-r--r-- 1 user user 0 Jul  4 19:37 20200222_a.txt
-rw-r--r-- 1 user user 0 Jul  4 19:38 20200222_b.txt
-rw-r--r-- 1 user user 0 Jul  4 19:39 20200222_c.txt
-rw-r--r-- 1 user user 0 Jul  4 19:40 20200222_d.txt

Hence my question; how would you "expand" the content of the ${fileprefix} variable when executing the ls command with the array of parameters?

I didn't found something interesting here: https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_02.html

3

1 Answer 1

2
... args+=( '-la "${fileprefix}"' )

Here, '-la "${fileprefix}"' is quoted, so it's stored as one element of the array, with the space, quotes, dollar sign, braces and everything. The ${fileprefix} isn't expanded, because the string is in single quotes. ls eventually gets that as one complete argument, and then complains about the space not being a valid option character.

Since you want ${fileprefix} to be expanded and used as a filename pattern / glob, you need to leave it unquoted. (It will also be word-split, which will matter if it ever contains whitespace (or you change IFS to something other than the default).) Also, you need to make -la a distinct element.

So:

args+=( -la ${fileprefix} )

(Note that echo "${args[@]}" is not a good way to look at an array: echo will print all arguments it gets joined by spaces, so it's hard to tell one array element with a space from two without, e.g. foo bar vs. foo and bar. printf ":%s\n" "${array[@]}" would be mildly better, at least until your data starts to contain newlines too, or the array can be empty.)

2
  • Will this also work for options passed as --key=value, given as --key=${ENV_VAR} e.g. psql ones?
    – s.k
    Jul 4, 2021 at 20:20
  • 1
    @s.k, you probably want to use "--key=$var", or --key="$var" to have the variable not word-split here. (Not sure if any of the PostgreSQL arguments can usefully take strings with spaces or so, but anyway.) In general, you put stuff in an array the same way you put them directly on a command line.
    – ilkkachu
    Jul 4, 2021 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.