Supercharge Your Command Line With Fish Shell

Linux has no lack of command-line shells. There’s ‘sh’, ‘bash’, ‘ksh’, ‘zsh’ and more. To get the most out of them, however, requires a bit of learning, time and work; something many of us don’t have time for. For those of us who want the power and pretty without the pain, there’s one shell that might be just what the doctor ordered.

At one time or another most Linux users will—either out of need or curiosity—venture onto the command-line. Unless their distribution has changed or modified the defaults, for most users it will mean being confronted with a pretty stark Bash prompt. Bash has been the de facto default shell for the majority of Linux distros for good reason. It’s extremely stable, powerful and flexible, while also being almost %100 POSIX standards-compliant. Some distros go the extra step and try to make bash a bit more user friendly, with coloring and things like tab completions to make finding commands and files easier. For the most casual of users, that alone might be enough. For those who would like a little more usability and friendliness from their terminal but aren’t command-line enthusiasts, trying to modify or enhance bash can be akin to trying to learn Cuneiform. There are other shells as mentioned above, like the very popular zsh. However, just like bash, getting  some ease-of-use and friendliness out of them is going to require a fair amount of tinkering. Fortunately, for those of us who want some of those cool features without having to get intimate with configuration files, there’s fish.

functionsI’m not sure if the intro to fish’s website is supposed to be some kind of pun or what, but believe me, fish is a modern, up-to-date and actively-developed shell. What really sets it apart is its user friendliness. Out of the box, it has most of the features the casual user would want and expanding on those doesn’t require a degree in programming. A refreshingly great feature of fish is its ‘help’ system.

Unlike most Linux shells that provide no more than cryptic ‘man’ files, fish installs a complete HTML user manual when it is installed. When a user types ‘help’ at fish’s command prompt, instead of a somewhat vague in-terminal listing of commands coming up, or something telling the user to “enter ‘man XXX’ for more”, fish opens your browser and presents you with a hyperlink-filled web page of all you may need. Features, options and commands are all well explained, most with examples to facilitate understanding. If you want help with a particular command, say with creating a function, at fish’s prompt you can simply type ‘help function’, and fish will open your browser on the section explaining functions.

Don’t like the default command prompt? No problem. At the default command prompt just type ‘fish_config’ and fish will open your browser with a configuration page where you can view examples of prompts and choose one you like, plus much more. This isn’t some remote server doing the configuration either. All this is right on your own system. The developers of fish put the most common things people might want to change in their shell into an easy-to-use interface. With just these two things alone, one can see what they mean by “user-friendly” but there’s more. The fish shell website also has a well done and comprehensive tutorial with screenshots, so the user can see how the topic they’re explaining would look.

Of course, once installed and first used, the most obvious immediate difference from what one may be used to is the colors. Fish is very colorful without having to set a thing. Out-of-the-box fish also does command completion, meaning it will give suggestions, “guesses” at what you want to do when you start typing. When first installed, though, it naturally doesn’t know what commands are on your computer, so you have to get it to create it’s completion list. It does know its own commands, so to get an idea of what it’s capable of. Just type ‘fish_’ and hit <TAB>. You’ll be presented with a list of commands fish already has matching what you typed, along with a short description of what each does.

First one you’ll want to execute is the “fish_update_completions” command. Simply add the “u” to the end of the “fish_” string you already typed, and fish will start showing the rest of the command as a suggestion, in front of what you’re typing. Press either the right-arrow key, or CTRL+f to let fish finish it for you. Press <ENTER> and watch fish start parsing all the man pages on the system, creating a database for it’s use. In a few moments the command prompt will come back, and fish will now know all the system’s command. To get an idea of what it can now do, type “fc” at the prompt, you’ll see fish automatically append the “-” to it. Fish knows all the “fc” (font configure) commands start with “-“, so it adds it right away.

Below the command prompt you’ll see all the “fc-” commands, with a short explanation of what they do. As before, you just start typing the next letter from the one in the list that matches what you wanted, and fish will place it after what you’ve already typed. All you need to do is hit right-arrow or CTRL+f to accept it. Or you can just hit CTRL+c to cancel it and return to the command prompt. If a command search produces several with the same next letter, just type however many more letters are needed to get to the one wanted, fish will constantly narrow it down as you type.

You’ll notice as you use fish that it seems to be learning, every time you start to type something, fish is suggesting a completion for it. Fish does this by first trying to match what you’re typing with a recent command, something you did earlier, and if there isn’t a match, it looks for one in its completion database. Like most shells, fish keeps a history of all the commands you’ve entered, thereby saving you from having to type the same thing twice. The history is searchable. You can just type the first few characters of a previous command and if fish’s default suggestion isn’t the one you wanted, press the up-arrow key. Fish will start replacing the command with ones that have the same starting string of characters. Find the one you want, then press <ENTER> for fish to execute it again.

This works for any command, including moving around the file system. Fish is very good at that. It can offer completions for navigating the file structure either from its history, or from the file structure itself. Oh, and for those times you might not want fish to remember where you’ve been or what you’ve done, just precede the command with a space. Anything started with a space character isn’t put into the history. Great for the aluminum-foil hat crowd.

fishFor me, one of the really useful and fun features of fish is the ability to create functions on the fly, then save them if I feel I’ll use them again, all without leaving the command-line. For example, one of the things I do often from the command-line is update my package list and system. I could do it from a GUI, but I’m one of those guys who likes to see and know what’s happening. Currently I’m running Linux Mint, so that involves two operations, ‘sudo apt update’ and ‘sudo apt upgrade’. While not really a lot to type each time, it would be nice to make it easier and faster. I believe computers should work for us, not the other way around. So, at the fish command prompt I created a function, as seen in this screenshot.

With fish, when you type the keyword “function”, it automatically goes into ‘edit’ mode. I gave the function a short, easy to remember name “suds”, my acronym for “sudo update system”. I type “function suds” then press <ENTER>, fish automatically jumps to the next line, and indents it to proper code. Next I typed the first command I wanted my function to do, “sudo apt update”. Press <ENTER> again, then typed “and sudo apt update”. Notice the inclusion of the word “and”? Fish has a special user-friendly way of combining commands that are not only easy to read, but quite powerful. The “and” keyword tells fish not to execute the next command until the first one is done, and not to execute it at all if there was an error produced by the first command.

If there is an error on the first command, instead of running the next one, fish outputs the error to the terminal, so the user can see it and know what went wrong, then exits the function. When I finished the second command-line, I hit <ENTER> and then typed “end”, another keyword fish knows, so it exits edit mode and returns to the command prompt. I can then run the command “suds” as though it was a system one. Because it’s a sudo command, fish prompts me for the administrative password, then apt updates the package cache. If all went well, apt then checks for updates and prompts me to accept any if they exist. I type “y” for “yes”, and apt installs them.

Now with most shells, if I wanted to keep this function beyond the current shell session, I’d have to open some resource or config file with an editor, then type it or copy-n-paste it over again there to keep it. Otherwise, once I exit the shell or logout, the function would be lost, as it only resides in system memory. Not terribly difficult, but I’m lazy, and fish has a better, easier way. I simply type “funcsave suds” at the command prompt, and fish saves my new function in its configs for me. Shiny!

In this article I’ve only scratched the surface of what fish is capable of. There are tons more features it has to make using the command-line easier and enjoyable, all of it covered in its excellent help system and website. While it might not pull long-time bash and zsh users away from their lovingly-massaged and configured shells, it’s definitely worth checking out. Especially if you’re an occasional CLI user who’d like a bit more than default bash, but doesn’t want to delve too much into editing resource and config files to get it. You don’t have to commit to anything or make any changes to try it out.

Most distros have it in their repositories, and like any shell, you can switch to it from an open terminal to try without making it permanent. Install it, open a terminal, and at your current prompt type “fish”. Your session shell will be switched, and you’ll be greeted by fish. Try it out, kick the tires, and when you’re done, simply type “exit”. Fish will return control to your original shell, nothing permanently changed. If you decide you like it, you can make it permanent, fish can even help you do that. Just type “help” at the fish prompt, and look for the section titled “How do I make fish my default shell?” It’s under the “Frequently asked questions”. If you decide it isn’t for you, uninstall it, no harm done. If you spend any time trying it, especially if you changed any of the default, it will have created a user configuration folder in “~/.config/fish”. If you’re not going to keep it on the system, you’ll likely want to delete that too.

There is one word of warning I should mention: using fish can be addicting. Enjoy!

Also check out...

Rob Boudreau
Rob started with Linux in 1996, and has been using it exclusively since '97. A strong advocate of free and open source software (FOSS), he's never been a programmer, his views are always from the perspective of a user. He actively supports FOSS financially, by contributing documentation, and by helping other users where and when he can.
  • Mike

    The command and tab completion feature is really slick and incredibly helpful!
    I often use fish to find ‘forgotten’ commands and those that do not come With and/or are not Referred To in man pages.