Search code examples
fish

fish shell functions not accessing user paths


I've recently started using fish, and I needed to use a jar file for google's bundletool.

As such, I needed to set up an alias/function for bundletool, and I chose a function since it seems more "fishy".

My function is simple:

function bundletool
    java -jar bundletool-all-1.12.1.jar $argv
end

The bundletool jar itself lives at ~/.local/bin, which is on my fish user path:

lase@laser-razer /m/c/U/matth [1]> echo $fish_user_paths
/home/lase/.local/bin /usr/local/go/bin /home/lase/.nvm /home/lase/.cargo/bin /home/lase/.cargo

In a regular shell, I can execute java -jar bundletool-all-1.12.1.jar, and the command runs as expected. However, in the function, fish doesn't seem to know about my fish_user_paths, and reports it cannot find the jar file.

To remedy this, I had to update my function to specify the full path:

function bundletool
    java -jar ~/.local/bin/bundletool-all-1.12.1.jar $argv
end

This works, but I feel like I'm doing something incorrectly. Should I be setting up my paths or functions in a different fashion?


Solution

  • Your function will run in the ordinary environment.

    It will run with the current $PATH [0] and, more importantly to you, the current working directory.

    What happens is this:

    java -jar bundletool-all-1.12.1.jar
    

    Will tell java to run the jar found at bundletool-all-1.12.1.jar.

    Notably, fish just hands java the string "bundletool-all-1.12.1.jar", and java will then not look at $PATH. It does not care about $PATH. It simply looks at "bundletool-all-1.12.1.jar", and tries to open a file by that name.

    And it will find that file, if it is in the current directory.

    And that's the reason this worked for you when you executed it interactively - because you happened to be in that directory

    And then you tried it with the function, but you tried it from a different directory, and so it didn't work.

    This works, but I feel like I'm doing something incorrectly. Should I be setting up my paths or functions in a different fashion?

    No, giving the full path to the file instead of relying on the working directory is the right thing to do.


    [0]: $fish_user_paths is just a variable you set, that fish will then take care to add to $PATH. $PATH is the actual variable that fish and other tools (including any command fish starts, if it wants to) will use to find commands.