Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expand bash array with globbing and extra words

In a CI/CD job, I have a shell variable X defined. It contains one or more words, each of which might have glob operators:

X="foo bar* 'a b c'"

Suppose bar* matches 3 files, bard, bare, and barf. And the file a b c exists and has 2 spaces in it.

I want to create a Bash array Y with these contents:

Y=(--arg foo --arg bard --arg bare --arg barf --arg 'a b c')

In other words: do glob/quote expansion, then map each word w to --arg $w.

A clean solution would allow spaces in the expanded names (to be honest, I'm never going to have that situation in this CI/CD code - but I or someone else might easily copy/paste this technique somewhere else where it does matter).

It would also be awesome if I could do glob/quote expansion without invoking all other possible shell expansions (e.g. process substitution & subshells) - I'm having trouble thinking of how to do that, though.

The only solution I've come up with so far is to use unprotected expansion:

Y=()
for a in $X; do
    Y+=(--arg "$a")
done

Is that the best I can do? Is it safe? It works well on the foo and bar* cases, but not well on the a b c case.

like image 626
Ken Williams Avatar asked Feb 01 '26 21:02

Ken Williams


1 Answers

To expand globs while honoring quotes (for grouping but not glob-suppression), but not expand variables or handle process substitutions or other dangerous syntax...

X="foo bar* 'a b c'"

IFS=
args=( )
while read -r -d '' word; do
  for item in $word; do
    args+=( --arg "$item" )
  done
done < <(xargs printf '%s\0' <<<"$X")

See this running in an online sandbox (where bard, bare and barf exist) at https://replit.com/@CharlesDuffy2/UnlawfulDecentApplicationserver#main.sh

The use of xargs printf '%s\0' has xargs do the work of word-splitting in an almost POSIX-compliant way (if you want something completely POSIX-compliant, you need to use the Python shlex module instead -- other Q&A on the site demonstrates how), and the unquoted expansion with an empty IFS performs globbing only.

like image 91
Charles Duffy Avatar answered Feb 04 '26 15:02

Charles Duffy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!