8
function f() {
    for arg; do
        echo "$arg"
    done
}

f 'hello world' 'second arg' '3rdarg'

this works fine:

hello world
second arg
3rdarg

but when do I assign $@ to some variable, and then it goes wrong:

function f() {
    local args="$@"
    for arg in "$args"; do
        echo "$arg"
    done
}

output:

hello world second arg 3rdarg

when I unquote the $args, then each argument was split into single word:

hello
world
second
arg
3rdarg

Lastly, I wonder if there's a way to define variable like $@. Any response will be appreciated.

oxnz
  • 835
  • 6
  • 16
  • 1
    The *generic* way to assign a new value to `$@` is: `set -- "first argument" "second argument" "etc"`. – Charles Duffy Nov 10 '15 at 04:46
  • ...but yes, as you've discovered here, you can't represent an array of strings in a variable whose type is a scalar (thus, a _single_ string). – Charles Duffy Nov 10 '15 at 04:47
  • Since the `$@` is an array as you indicated, then how to manipulate it as an regular array variable, such as unset `${array[1]}`, `${array[1]} = 'hello'`, etc? Or it's just s special case, and the only way to manipulate is use the `shift`,`unshift` and `set`? Additionally, the `'-p'` option of the 'declare' built-in could print the related type of the var, could it be used against the $@ var as well? – oxnz Nov 10 '15 at 05:43
  • Yes, it's a special case (it's the only array available in POSIX sh, with which standard bash complies, which doesn't otherwise support arrays). No, `declare -p` and like tools don't work for `"$@"`. – Charles Duffy Nov 10 '15 at 14:01

1 Answers1

7

You'll need to use an array:

function f() {
    local args=("$@")             # values in parentheses
    for arg in "${args[@]}"; do   # array expansion syntax
        echo "$arg"
    done
}
glenn jackman
  • 238,783
  • 38
  • 220
  • 352