Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

build argument lists containing whitespace

In bash one can escape arguments that contain whitespace.

foo "a string"

This also works for arguments to a command or function:

bar() {
    foo "$@"
}

bar "a string"

So far so good, but what if I want to manipulate the arguments before calling foo?

This does not work:

bar() {
    for arg in "$@"
    do
        args="$args \"prefix $arg\""
    done

    # Everything looks good ...
    echo $args

    # ... but it isn't.
    foo $args

    # foo "$args" would just be silly
}

bar a b c

So how do you build argument lists when the arguments contain whitespace?

like image 719
tarsius Avatar asked Jan 04 '09 19:01

tarsius


3 Answers

There are (at least) two ways to do this:

  1. Use an array and expand it using "${array[@]}":

    bar() {
        local i=0 args=()
        for arg in "$@"
        do
            args[$i]="prefix $arg"
            ((++i))
        done
    
        foo "${args[@]}"
    }
    

    So, what have we learned? "${array[@]}" is to ${array[*]} what "$@" is to $*.

  2. Or if you do not want to use arrays you need to use eval:

    bar() {
        local args=()
        for arg in "$@"
        do
            args="$args \"prefix $arg\""
        done
    
        eval foo $args
    }
    
like image 191
tarsius Avatar answered Nov 12 '22 04:11

tarsius


Here is a shorter version which does not require the use of a numeric index:

(example: building arguments to a find command)

dir=$1
shift
for f in "$@" ; do
    args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
like image 25
Jaen Avatar answered Nov 12 '22 05:11

Jaen


Use arrays (one of the hidden features in Bash).

like image 1
JesperE Avatar answered Nov 12 '22 03:11

JesperE