8

I'm aware of how to get the last argument passed to a function but I'm wondering how to get all the arguments of a function after the first two:

For instance:

function custom_scp(){
    PORT=$1
    USER=$2
    SOURCES=`ALL_OTHER_ARGS`
    scp -P $PORT -r $SOURCES $USER@myserver.com:~/
}

So sending three files to the remote home directory would look like

$ custom_scp 8001 me ./env.py ./test.py ./haha.py
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
ted
  • 13,596
  • 9
  • 65
  • 107
  • 3
    BTW, see https://wiki-dev.bash-hackers.org/scripting/obsolete -- `function foo() {` is mixing POSIX sh and ksh function declaration formats in a way that's compatible with *neither* POSIX sh *nor* with legacy ksh. Pick one or the other: `foo() {` is the POSIX form, `function foo {` is the ksh form. – Charles Duffy Feb 13 '19 at 20:34
  • 3
    BTW, re: use of lowercase names in my answer, that's deliberate. `USER`, for example, is a reserved variable name. By overwriting it, you're potentially breaking other commands run later in the same session. See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html -- all-caps names are used for variables that modify system behavior, lower-case names are reserved for application use. Setting a shell variable with the same name as an environment variable overwrites the latter, so the namespace rules apply to both sets. – Charles Duffy Feb 13 '19 at 20:38

2 Answers2

12

Just shift off the front ones as you're done with them; what's left will be in "$@".

This has the advantage of being compatible with all POSIX shells (the only extension used in the below is local, and it's a widespread one, even available in dash).

custom_scp() {
  local user port  # avoid polluting namespace outside your function
  port=$1; shift   # assign to a local variable, then pop off the argument list
  user=$1; shift   # repeat
  scp -P "$port" -r "$@" "${user}@myserver.com:~/"
}
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
7

You can use array slice notation:

custom_scp() {
    local port=$1
    local user=$2
    local sources=("${@:3}")

    scp -P "$port" -r "${sources[@]}" "$user@myserver.com:~/"
}

Quoting from the Bash manual:

${parameter:offset}
${parameter:offset:length}

If parameter is @, the result is length positional parameters beginning at offset.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578