Search code examples
fish

Defining new fish commands in a script and parse arguments


Quick question. Is it possible to define new commands by scripting in fish? I want to program a new command along the lines of this:

newFunction --flag1 flag1Input --flag2 flag2Input then space delimited arguments

This new function would only by using already-defined commands in a way that functions do, I just want to be able to pass flags to this new function. Is this possible, or do I have to use another language like Python to create an executable for my hypothetical command?


Solution

  • Sure! Just like in bash (or any interpreted language really) all you need to do is create a file, give it execute permissions and write your fish script in it!

    • The first line of the file should be #!/usr/bin/fish (Modify that path if your fish installation is located elsewhere. You can check by calling which fish)
    • Start writing your fish script, your arguments will be $argv[1], $argv[2]... etc
    • Give your script execute permissions: chmod +x myscript
    • Put your script somewhere in your $PATH (for example /usr/local/bin) so that you can call it like other commands in the system.

    Here's a useless example script that prints out the arguments you passed:

    #!/usr/bin/fish
    
    for i in $argv
            echo $i
    end
    

    To parse the arguments you could use the argparse with fish_opt.

    What you do is: You specify what your flags are with fish_opt like so:

    set -l options (fish_opt -s n -l name --required-val)
    set options $options (fish_opt -s h -l help)
    

    where -s is followed by the short form of your flag and -l is followed by the long form.

    Then you use argparse to parse your arguments like this:

    argparse $options -- $argv
    

    Then you can check on your flags like this:

    if set -q _flag_help
        echo "Haalp!"
        return 0
    end
    

    Notice that whatever your flag name is, it's gonna be set to a variable of the format _flag_myflag

    Here's a complete example:

    #!/usr/bin/fish
    
    set -l options (fish_opt -s n -l name --required-val)
    set options $options (fish_opt -s h -l help)
    
    argparse $options -- $argv
    
    if set -q _flag_help
        echo "Haalp!"
        exit 0
    end
    
    if set -q _flag_name
        echo My name is $_flag_name
        exit 0
    end
    

    Now let's call it:

    $ myscript
    $ myscript --help
    Haalp!
    $ my_script --name "Anthony"
    My name is Anthony