1

Lets assume I have some python argparse script which I would like to kind of alias using a bash function.

Let us assume this python script takes four arguments:

--arg1
--arg2
--arg3
--arg4

What I would like to achieve is taking the first two arguments at fixed positions, and after that to infinitely add the optional arguments.

function foo()  {  python3 script.py --arg1 "$1" --arg2 "$2" "$@";  }

So something like this:

foo value1 value2 --arg3 value3 --arg4 value4

However, $@ starts counting from 1.

How can I achieve this?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Peterhack
  • 941
  • 4
  • 15
  • 34
  • 1
    Not sure but I smell like '$@' is an array, so you can index it from 5th position. Something like `"${$@:5}"`. You can experiment with that – deathangel908 Mar 26 '19 at 12:26

3 Answers3

2

Slice the positional arguments array after the 2nd to the rest of the list as below. Also drop the non-standard keyword function from the definition.

foo() {  
   python3 script.py --arg1 "$1" --arg2 "$2" "${@:3:$#}"
}

Also note that the last argument to $# is optional in slicing the list. Without the same it is understood that the end is upto the final positional argument.

Also this way of argument parsing could get tricky if more positional arguments get added or the order of the arguments gets changed. For a much more efficient argument parsing, consider using the getopts (its equivalent Python module).

Inian
  • 80,270
  • 14
  • 142
  • 161
1

Save $1 and $2 to local variables, and then use shift to shift the variables over so that $@ doesn't include them anymore.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
1

$@ is indeed an array in Bash, so you can access an arbitrary item (items) with the syntax ${@:start:length}:

function foo() {
  python3 script.py --arg1 "$1" --arg2 "$2" "${@:3}"
}

Here, when length is omitted, it's assumed to be long enough to contain all remaining items.

shift then use $@ is an alternative:

function foo() {
  arg1="$1"
  arg2="$2"
  shift 2
  python3 script.py --arg1 "$arg1" --arg2 "$arg2" "$@"
}
iBug
  • 35,554
  • 7
  • 89
  • 134