How to Use SDKMAN! with Fish Shell: A Detailed Guide
TL;DR: While SDKMAN! is primarily designed for Bash/Zsh shells, you can make it work with Fish shell using a simple wrapper function that bridges the gap between Fish and Bash.
The Problem with SDKMAN! and Fish Shell
If you're a Fish shell user trying to use SDKMAN! (Software Development Kit Manager), you've probably encountered errors like:
~/.sdkman/etc/config (line 1): Unsupported use of '='. In fish, please use 'set sdkman_auto_answer false'.
This happens because SDKMAN!'s scripts are written in Bash/Zsh syntax, which isn't compatible with Fish shell's unique syntax.
The Quick Solution: A Fish Shell Wrapper
Instead of converting all of SDKMAN!'s scripts to Fish (which would be time-consuming and break with updates), we can create a simple wrapper function that lets Fish and SDKMAN! work together seamlessly.
Step 1: Install SDKMAN!
First, make sure you have SDKMAN! installed:
curl -s "https://get.sdkman.io" | bash
Step 2: Create the Wrapper Function Initialization Script
First, create a new file in your Fish config directory if it doesn't already exist:
mkdir -p ~/.config/fish/conf.d
Then, create a new file called sdkman-init.fish
in the conf.d directory:
touch ~/.config/fish/conf.d/sdkman-init.fish
Finally, write the script in your favorite text editor, by following these steps:
Open your terminal and type the command to open the file in your preferred text editor. For example, using
nvim
:nvim ~/.config/fish/conf.d/sdkman-init.fish
Copy and paste the following script into the file:
function sdk --description 'SDKMAN! wrapper for Fish shell' set -q SDKMAN_DIR; or set -gx SDKMAN_DIR "$HOME/.sdkman" set -q SDKMAN_CANDIDATES_API; or set -gx SDKMAN_CANDIDATES_API "https://api.sdkman.io/2" if test -f "$SDKMAN_DIR/var/platform" set -gx SDKMAN_PLATFORM (cat "$SDKMAN_DIR/var/platform") end command bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && sdk $argv" if contains -- "$argv[1]" "install" "uninstall" "use" "default" "env" set -l candidates (cat "$SDKMAN_DIR/var/candidates") for candidate in (string split ',' $candidates) set -l candidate_dir "$SDKMAN_DIR/candidates/$candidate/current" if test -L "$candidate_dir"; or test -d "$candidate_dir" if not contains "$candidate_dir/bin" $PATH set -gx PATH "$candidate_dir/bin" $PATH end end end end end complete -c sdk -f complete -c sdk -a "install uninstall list use current upgrade version default home env clear help offline selfupdate update flush" -d "SDKMAN! command" complete -c sdk -n "__fish_seen_subcommand_from install uninstall list use current upgrade version default home" -a "(cat $HOME/.sdkman/var/candidates | string split ',')" -d "SDK candidate"
Save the file and exit the text editor.
Step 3: Initialize fish shell with sdkman
source ~/.config/fish/conf.d/sdkman.fish
Get the complete file as a gist on my github.
How It Works
The wrapper function:
Sets up necessary SDKMAN! environment variables.
Uses Bash to execute SDKMAN! commands.
Updates Fish's PATH after installing or switching versions.
Provides command completion for common SDKMAN! operations.
Using SDKMAN! in Fish
Now you can use SDKMAN! commands just like in Bash:
# List available Java versions
sdk list java
# Install a specific Java version (Eclipse Temurin in this case)
sdk install java 17.0.2-tem
# Use a specific Java version
sdk use java 17.0.2-tem
Conclusion
This wrapper provides a practical solution for Fish shell users who want to use SDKMAN! without converting all its scripts or switching shells. It maintains compatibility with SDKMAN! updates while providing most of the functionality you need for day-to-day development.
FAQ
Q: Will this break when SDKMAN! updates? A: No, since we're using Bash to execute SDKMAN! commands, it should continue working with updates.
Q: Does this work on all operating systems? A: Yes, as long as you have both Fish and Bash installed.
Q: Can I contribute to making SDKMAN! work natively in Fish? A: Yes! The SDKMAN! project is open source and welcomes contributions.
Subscribe to my newsletter
Read articles from Pawan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by