Skip to main content
Added description of what was the problem with the original code.
Source Link
user79743
user79743

(in Bash) You can change to an array of values:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"

} 

find2 /tmp/test -name "hello.c"

find2 /tmp/test -name "hello.c"

But this works and is quite simpler:

find2() {
    ARGS=( "/usr/bin/find" "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"
}

find2 /tmp/test -name "hello.c"

Of course, the direct way also work (in any shell with functions):

find2() {    /usr/bin/find "$@";   }

find2 /tmp/test -name "hello.c"

Why the original code failed?

To "see" what the code is doing you may use set -x or better yet , replace the echo for printf, as this:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

When you execute it, you see:

$ ./script.sh
<CALLING:> </usr/bin/find> </tmp/test> <-name> <hello.c> 

Each argument is a separate element (note the position of the <>).

However, in your original code (adding printf):

function find2 {

    ARGS="/usr/bin/find"
    while [[ $# -gt 0 ]]; do
        ARGS="$ARGS '$1'"
        shift
    done
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    $ARGS

}   

find2 /tmp/test -name "hello.c"

You will get, on execution:

$ ./script.sh
<CALLING:> </usr/bin/find '/tmp/test' '-name' 'hello.c'>

All the values are a long text line, not separate arguments (note the position of the <>).

(in Bash) You can change to an array of values:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

But this works and is quite simpler:

find2() {
    ARGS=( "/usr/bin/find" "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"
}

find2 /tmp/test -name "hello.c"

Of course, the direct way also work (in any shell with functions):

find2() {    /usr/bin/find "$@";   }

find2 /tmp/test -name "hello.c"

(in Bash) You can change to an array of values:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"

} 

find2 /tmp/test -name "hello.c"

But this works and is quite simpler:

find2() {
    ARGS=( "/usr/bin/find" "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"
}

find2 /tmp/test -name "hello.c"

Of course, the direct way also work (in any shell with functions):

find2() {    /usr/bin/find "$@";   }

find2 /tmp/test -name "hello.c"

Why the original code failed?

To "see" what the code is doing you may use set -x or better yet , replace the echo for printf, as this:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

When you execute it, you see:

$ ./script.sh
<CALLING:> </usr/bin/find> </tmp/test> <-name> <hello.c> 

Each argument is a separate element (note the position of the <>).

However, in your original code (adding printf):

function find2 {

    ARGS="/usr/bin/find"
    while [[ $# -gt 0 ]]; do
        ARGS="$ARGS '$1'"
        shift
    done
    printf '<%s> ' CALLING:  "${ARGS[@]}"; echo
    $ARGS

}   

find2 /tmp/test -name "hello.c"

You will get, on execution:

$ ./script.sh
<CALLING:> </usr/bin/find '/tmp/test' '-name' 'hello.c'>

All the values are a long text line, not separate arguments (note the position of the <>).

Source Link
user79743
user79743

(in Bash) You can change to an array of values:

find2() {

    ARGS="/usr/bin/find"
    ARGS+=( "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"

}

find2 /tmp/test -name "hello.c"

But this works and is quite simpler:

find2() {
    ARGS=( "/usr/bin/find" "$@" )
    echo CALLING:  "${ARGS[@]}"
    "${ARGS[@]}"
}

find2 /tmp/test -name "hello.c"

Of course, the direct way also work (in any shell with functions):

find2() {    /usr/bin/find "$@";   }

find2 /tmp/test -name "hello.c"