I have two versions of python installed. Therefore if I need to download packages using pip , I have to use either of :

  1. python3.9 -m pip [args]
  2. python3.8 -m pip [args]

What I want is that I want to use pip39 as a substitute of pythin3.9 -m so that if I run pip39 install something or pip39 freeze then the appropriate commands are executed.

I wrote the following function:

pip39(){python3.9 -m pip "$1"}

It works well for pip39 freeze since freeze is a single argument. But for pip39 install something it gives error since 2 arguments were passed and only the first will be taken by bash.

So how to put multiple args in"$1" ?

  • just put it after first one, or create getops fuction
    – klerk
    Commented Oct 29, 2020 at 6:58
  • 1
    Isn't an alias (alias pip39='python3.9 -m pip') all you need?
    – DonHolgo
    Commented Oct 29, 2020 at 10:23
  • @DonHolgo , Can an alias take arguments? I dont know , I will try that
    – Jdeep
    Commented Oct 29, 2020 at 10:28
  • @NoahJ.Standerson The alias itself is unaware of the arguments, the shell would just replace pip39 with python3.9 -m pip in the command line. Since the arguments simply follow that, it seems sufficient for your case.
    – DonHolgo
    Commented Oct 29, 2020 at 11:03

1 Answer 1


In Bourne-like shells, "$1" expands to the first argument of the function (or of the script if not expanded inside a function) or to the empty string if not, "$2" would be the second, "$3" third... "${10}" tenth¹, "$@" expands to all supplied arguments.

${1+"$1"} expands to the first argument if supplied and nothing (not even an empty string) if not. So ${1+"$1"} ${2+"$2"} would expand to up to 2 of the first arguments of the function. In the yash or zsh shells, that can be simplified to "${@[1,2]}" (even to "$@[1,2]" in zsh), and in ksh93, bash and zsh to "${@:1:2}".

pip39() {python3.9 -m pip "$1"} is zsh syntax however. In bash or other Bourne-like shell, you'd need pip39() { python3.9 -m pip "$1";} (or simply pip39() python3.9 -m pip "$1" in the Bourne shell and most Bourne-like shells, though not bash, posh nor yash).

So here, in bash (as you tagged your question) or zsh (as in the syntax of the code in your question), you'd want:

pip39(){ python3.9 -m pip "$@";}

To pass all the arguments of pip39 to python3.9, that code being Bourne and POSIX compatible.

Or to pass only a limited number of arguments (here 3 as an example):

pip39(){ python3.9 -m pip "${@:1:3}"; } # ksh93, bash, zsh
pip39(){ python3.9 -m pip "${@[1,3]}"; } # zsh, yash
pip39(){ python3.9 -m pip ${1+"$1"} ${2+"$2"} ${3+"$3"}; } # any Bourne-like shell

¹ Not in the Bourne shell where you're limited to 9. $10 would be either like ${10} or ${1}0 depending on the shell (POSIX requiring the latter unfortunately) so should be avoided.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .