Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fish function option/param parser

Tags:

parsing

fish

It seems that there is some work in progress to add support for this in the future:

https://github.com/fish-shell/fish-shell/issues/478
https://github.com/xiaq/fish-shell/tree/opt-parse

But in the meantime, what's the recommended way to deal with this? Should I just parse $argv? If so do you have some tips/best practices?

like image 839
gonz Avatar asked Apr 16 '13 23:04

gonz


Video Answer


3 Answers

Parsing $argv is fine for basic scenarios but can otherwise become tedious and error prone.

Before fish had its own argument parsing solution, the community created:

  • getopts.fish

As of fish 2.7.0, you can use fish's built-in option parser: argparse

function foo --description "Example argparse usage"
  set --local options 'h/help' 'n/count=!_validate_int --min 1'

  argparse $options -- $argv

  if set --query _flag_help
    printf "Usage: foo [OPTIONS]\n\n"
    printf "Options:\n"
    printf "  -h/--help       Prints help and exits\n"
    printf "  -n/--count=NUM  Count (minimum 1, default 10)"
    return 0
  end

  set --query _flag_count; or set --local _flag_count 10

  for i in (seq $_flag_count); echo foo; end
end

To see the full extent of what's possible, run argparse -h or argparse --help.

like image 57
Dennis Avatar answered Oct 18 '22 01:10

Dennis


I'm note sure if it is a best practice, but in the meantime you could do something like this:

function options
  echo $argv | sed 's|--*|\\'\n'|g' | grep -v '^$'
end

function function_with_options
  for i in (options $argv)
    echo $i | read -l option value

    switch $option
      case a all
        echo all the things
      case f force
        echo force it
      case i ignore
        echo ignore the $value
    end
  end
end

Output:

➤ function_with_options -i thing -a --force
ignore the thing
all the things
force it
like image 34
terje Avatar answered Oct 18 '22 03:10

terje


You can do this:

for item in $argv
    switch "$item"
        case -f --foo
        case -b --bar
    end
end

The above does not support writing short options in a single argument -fbz, option values --foo=baz, --foo baz or f baz, negative assignment --name!=value, end of options -- and dashes - and -- are always part of the argument.

To address these issues, I wrote a getopts function.

getopts -ab1 --foo=bar baz

Now look at the output.

a
b    1
foo  bar
_    baz

The items on the left represent the option flags or keys associated with the CLI. The items on the right are the option values. The underscore _ character is the default key for arguments without a key.

Use read(1) to process the generated stream and switch(1) to match patterns:

getopts -ab1 --foo=bar baz | while read -l key option
    switch $key
        case _
        case a
        case b
        case foo
    end
end

See the documentation.

like image 3
Jorge Bucaran Avatar answered Oct 18 '22 01:10

Jorge Bucaran