How do you pass arguments to custom zsh functions?
Asked Answered
zsh
K

2

50

How do you pass arguments to custom zsh functions?
For instance:

function kill_port_proc(port) {
    lsof -i tcp:<port interpolated here>| grep LISTEN | awk '{print $2}'
}

I'm seeing so many examples online with ZSH functions, but there barely anything on passing arguments and interpolating them.

Kanazawa answered 12/3, 2019 at 17:47 Comment(0)
S
59

When defining a function, you cannot specify required arguments. That's why using both the function keyword and parens () seems useless to me.

To get the passed arguments, use positional parameters.

The positional parameters provide access to the command-line arguments of a shell function, shell script, or the shell itself; [...]

The parameter n, where n is a number, is the nth positional parameter. The parameter $0 is a special case [...]

About the $0 positional parameter:

The name used to invoke the current shell, or as set by the -c command line option upon invocation.

If the FUNCTION_ARGZERO option is set, $0 is set upon entry to a shell function to the name of the function, and upon entry to a sourced script to the name of the script, and reset to its previous value when the function or script returns.

Using your example:

function kill_port_proc {
    lsof -i tcp:"$1" | grep LISTEN | awk '{print $2}'
}

Personaly, I like to document the function by, at least, adding the function signature prior to the definition.

Then, I declare local parameters for each arguments and readonly parameters when I want to protect them from unexpected modification.

If the argument is mandatory, I use a special parameter expansion form:

${name?word}

${name:?word}

In the first form, if name is set, or in the second form if name is both set and non-null, then substitute its value;

otherwise, print word and exit from the shell. Interactive shells instead return to the prompt.

If word is omitted, then a standard message is printed.

How I would write your example:

# kill_port_proc <port>
function kill_port_proc {
    readonly port=${1:?"The port must be specified."}

    lsof -i tcp:"$port" | grep LISTEN | awk '{print $2}'
}
Shinberg answered 14/3, 2019 at 20:52 Comment(4)
If leave out "()" when declaring the function every time you source your bash_profile the function will be executed.Arteaga
@Arteaga My answer is specific to Zsh. Use a POSIX compliant syntax to be portable across the shells.Shinberg
When will the first form be used?Syringe
Thanks Damien, I used this to make this and I am happy with it :)Involucel
E
11
my_function() {
  if [ $# -lt 2 ]
  then
    echo "Usage: $funcstack[1] <first-argument> <second-argument>"
    return
  fi

  echo "First argument: $1"
  echo "Second argument: $2"
}

Usage

$ my_function
Usage: my_function <first-argument> <second-argument>

$ my_function foo
Usage: my_function <first-argument> <second-argument>

$ my_function foo bar
First argument: foo
Second argument: bar
Experientialism answered 19/8, 2022 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.