user1011471 user1011471 - 2 months ago 6
Bash Question

Portable way to build up arguments for a utility in shell?

I'm writing a shell script that's meant to run on a range of machines. Some of these machines have bash 2 or bash 3. Some are running BusyBox 1.18.4 where

exists but

  • /bin/bash --version
    doesn't return anything at all

  • foo=( "hello" "world" )
    complains about a syntax error near the unexpected
    both with and without the extra spaces just inside the parens ... so arrays seem either limited or missing

There are also more modern or more fully featured Linux and bash versions.

What is the most portable way for a bash script to build up arguments at run time for calling some utility like
? I can build up a string but feel that arrays would be a better choice. Except there's that second bullet point above...

Let's say my script is
and you call it like so:
foo -o 1 .jpg .png

Here's some pseudo-code


# handle option -o here
shift $(expr $OPTIND - 1)

# build up parameters for find here
parameters=(my-diretory -type f -maxdepth 2)
if [ -n "$1" ]; then
parameters+=-iname '*$1' -print

while [ $# -gt 0 ]; do
parameters+=-o -iname '*$1' -print

find <new positional parameters here> | some-while-loop


If you need to use mostly-POSIX sh, such as would be available in busybox ash-named-bash, you can build up positional parameters directly with set

$ set -- hello
$ set -- "$@" world
$ printf '%s\n' "$@"

For a more apt example:

$ set -- /etc -name '*b*'
$ set -- "$@" -type l -exec readlink {} +
$ find "$@"