Best part of fish is how little config is needed. I’m 41, married with kids. Old AF by some standards. I have zero patience with wasting my time configuring tooling.
zsh felt like it fought me every step of trying to configure it to be halfway decent. And a lot of zsh scripts out there aren’t exactly bulletproof. It shouldn’t matter, except for the fact that if you use the shell with any regularity you will inevitably bump into edge cases that weren’t handled well by a mishmash of user scripts whose provenance is mostly copy/paste with little understanding of why it is all needed.
It has a submodule based plugin system (loader in conf.d), an async git prompt, my aliases, and a few env vars set. It needs no maintenance because fish provides almost everything already.
The only thing I want from fish at this point is to make async prompts first-class. They are best handled by the shell, not user code, due to the state tracking.
I use bash and also have no patience for configuring tooling. Your fish dotfiles are more complicated than my bash ones. I used to work on a team where many of the other engineers used fish. I never saw it doing anything I couldn't do in bash, although it looked a little fancier. But the annoying thing was when they asked me for help, and none of the commands I gave them worked in fish. It made for very slow troubleshooting sessions.
i am using fish for more than a decade and i don't have any dotfiles for it. (do i win? :-p )
your commands to help not working in fish? that is rather surprising. i would think that fish users should be aware that shell specific things in fish are different, so they should have been able to cope and translate as needed.
and it's not what you can do in fish that makes it special. it's how you do it. the syntax coloring, the completions, the syntax itself...
the key thing for me is how it handles searching history and autosuggestions. i just learned how to somehow recreate this setup in zsh, and i am very curious if bash can do that too: https://news.ycombinator.com/item?id=37274207
btw i believe bash got a lot better at command completion after fish popularized the idea.
I went through the initial config wizard of zsh exactly once, almost a decade ago[1]. It took me maybe 5-10 minutes, and even though I don't fully understand what each command means, I haven't modified it in all this time, and it works well. I really don't think this was any significant waste of time or tedious task - I was just as free to simply ignore it.
Most of the remainder of my zsh config are prompt utilities and other things I've added over the years. I don't use or really need any plugins, though if I needed, last time I tried zplug it was really easy to set up and use.
Agree with everything you said. If I didn't have to write /bin/sh compatible scripts for work, I would switch to Fish for similar reasons. From a UX point of view it's indisputably ahead of every other shell and it isn't even close, to the point I'm surprised it hasn't been adopted as the default by an OS like Mac yet. I can walk my family members through terminal things with Fish and nobody gets frustrated or quits. I can't say that about other shells.
> zsh felt like it fought me every step of trying to configure it to be halfway decent.
oh-my-zsh is a lifesaver here. I have a very small dotfile that delegates most of the config to omz, which I have in a bare repo that I clone onto each new machine. It took maybe an hour a few years ago to settle on the plugins I wanted and put the repo together, and each new machine now takes 5-10 minutes to get up and running.
I've been using Fish as my login shell for more than a decade now. Unlike many other commenters here, I also use it for scripting. For simple stuff, it's way nicer for writing scripts because the language just has has fewer gotchas than bash.
If you're just reading instructions online, translating between examples given in bash and fish is trivial. I see people talk about that being an issue for them and I don't understand it; it's literally never given me trouble.
The one thing that keeps me from using it more often for scripting is the lack of a fail-on-error mode (similar to `set -e` on bash). I know it is hard to get this to behave well in all cases (e.g. pipefail) but I don't want to do much scripting without it.
The other ones that annoy me are shell redirection from fish functions and some job control issues, which I'm hoping will both be fixed when job control is rearchitected as part of the ongoing Rust port.
I still use bash in CI, and for Linux scripts that I distribute to others. For macOS automation, I use zsh since it's the default nowadays.
My fish scripting is mostly for personal use and occasionally little wrappers on servers that I own. Sometimes I'll share a bit of fish code with other fish users at work, too.
Fail-on-error would be nice and help make the case for using fish in more places. At organizations where no one really knows bash that well anyway, fish would actually be nicer for scripting than bash if it had just a few more goodies like that imo.
I've used fish for about 5 years now, and I don't really wanna go back. Out of the box, without any addons at all, it does everything my old zsh setups did, with a package manager and plugins. The only change I've made to it was spacefish (now starship.rs)
You may also want to try z, and, err... I don't have my config with me, but I have a plugin that notifies me if a long-running background command finishes, which is really handy.
I use starship with zsh. The biggest value is showing the current environment for any project without any config. Shows the active node version, Python venv, k8s context, all without having to think about it.
The other day an AWS command was rejected with a generic 403 error and at a glance I realized I'd forgotten to switch the default profile—without starship I suspect I would have spent a while troubleshooting my SSO login instead of just switching profiles.
I also use starship with barely any custom config (like fish). It shows me the environment I'm in for a project, including which versions of tools are active and which server I'm currently connected to (if any). And it looks pretty enough.
Big one for me was out of the box support for showing current kubernetes context. Very helpful if you work in multiple kubernetes clusters and in particular if you move around namespaces helping others.
Doable with configuration and either lots of work or plugins in other shells but the combo of fish + starship.rs offers a lot for little setup.
While there is a tool called `babelfish` that will automatically convert bash to fish, in practice it's rarely needed.
You can run bash scripts from fish.
For sourcing, often it makes sense to use direnv to automatically load variables. -- For "just source this one time", in the worst case you can run a bash shell, source that, then run a fish shell.
I tried zsh at some point, but I got the impression that it's basically the same as bash out of the box, and you need to spend time customizing it to see the benefits. I don't want to spend time customizing my shell, I want it to work out of the box.
Fish is noticeably better than bash out of the box, with absolutely no customization. Magic autocomplete is life-changing.
I was using fish on Ubuntu in college. First job gave me a macbook and I set it up using fish. We only had one devops guy and he shared the app set up docs and all the scripts were available only in zsh or bash. I was okay with switching to zsh tbh. But the dude stopped me and then spent half a day learning and then updating all the docs with fish scripts as well! Bless him!
This is true. However I was calling out, wrt fish, the only two additional "plugin" type things I add in order to have a comfortable shell environment.
Fish conveniently provides history based autocomplete so I don't need to setup some plugin for that.
Yeah. I love the default starship and install it on every shell I use, currently PowerShell + fish + bash. It shows me all kinds of useful info like which k8s cluster I'm logged into, which AWS/Azure/GCP account, whether the current directory has uncommitted git changes...
When you open a new shell, by default it'll say something like `user@hostname: cursor`. Starship lets you change that to whatever you want, but out of the box it hides unnecessary information, and shows you stuff like the your language and package versions, if you're navigated into a git repo, for example. Take a look at it yourself, there's a lot you can do
I love their tagline. Very funny. I used it for a while and liked it enough but their development strategy is explicitly against having configurable options. A few things nagged me and there was no way to change the behavior so I switched to zsh and made it work like fish, but the way I like it instead. For me this was a good decision and I recommend it. (I am not a fan of oh-my-zsh or plugin managers etc either)
can you elaborate on what nagged you? i am just curious, not critical.
i use fish, zsh and now also elvish. the main thing for me is autosuggestion and getting history with uparrow. zsh has a module for autosuggestion. elvish has uparrow history (but only matches at the start). so fish still wins over the others. elvish comes second because typing a command and hitting uparrow once is almost like autosuggestion. but i could not find a way to get that in zsh. i also prefer the way fish and elvish handle blocks over the traditional sh-shell style.
I'm unsure what specific behaviour you want from zsh and the up key, but it provides more than one up-line-*¹² function out of the box. Also, you can add any behaviour you wish with a custom zle function. That said, I understand some people prefer to just use something with the default settings.
this feature helps because in 90% of cases i can type some-word and have autosuggestion show me the right command, so i just need to hit right arrow and enter to run it. but, if the suggestion is wrong, i can instead hit up arrow and search for a another history entry.
in zsh currently, i can get autosuggestions, but if the suggestions is wrong, i have to type ctrl-A and retype some-word in order to search the history. i want to be able to do that without retyping, the way it is done in fish.
elvish only has the uparrop feature which gets me there halfway, i can type something, and then hit uparrow to find a matching command. in most cases the first hit is the one i want, but if not i keep searching.
i prefer to also have the autosuggestion because often i don't remember that i have a similar command already, and the autosuggestion provides that hint.
together these are the two most useful features that i want from a shell.
That is the difference between the up-line-or-history and up-line-or-search functions that I linked above. The default Up binding is the -history function, whereas the -search function in unbound by default. There are pattern variants too, if you don't like the prefix only checks.
If you also need to mimic the fish behaviour of C-r mid-command because your suggestion wasn't correct, then that does need a custom function to bind to C-r as you have to provide ${L,}BUFFER to populate the search pattern like fish does.
ah, thank you. that actually helps a lot. i don't use zsh as much, but it's good to know that this feature is available. i don't use ctrl-R in fish yet, so i won't miss that.
I don't remember exactly now but I have been on unixlikes forever and I am not too much into fuzzyness in general. I think it was treating upper and lower case characters the same in completions and such. Things of that nature - maybe not exactly that - but when I went to do some research about how to configure it, I realized it was not possible and that was by design. It's very good software that a lot of other shells take inspiration from but I don't agree with their methodology so I took the best bits and made zsh do them, which it can do easily. I didn't use zsh before that and now I am a huge fan.
If anybody who needs this wants to give ZSH a go, I recommend starting with only a few settings and only add new ones if you understand what they do. Same goes for plugins. I do not recommend starting with oh-my-zsh at all - which IMO is a glorified alias database anyway.
The biggest screw up is that fish is not bash compatible. I'm just too used to bash and am not willing to change that because there are corporate systems where I only have access to bash and nothing else; and cannot install fish.
It will just be hurtful to need to keep switching between different scripting languages; I will never be able to do so comfortably and with muscle memory.
No, I mean creating some kind of quick program from the prompt itself.
Like for instance bulk renaming of files from the prompt, there is no way I could do that quickly in fish's language and having to switch to bash to do that would be unnecessarily slow. Might as well stick to bash.
What I mean to say is that fish would hurt my productivity rather than boost it.
This is the reason I was amenable to making the jump to zsh.
With the customizations I have in my shell, my bash startup times were creeping into the multi-second territory, but I got a better UX and faster shell startup without having to learn new syntax for simple shell loops.
learning any new tool takes a bit of time. but i believe you are overestimating the effort it takes to learn fish syntax. it is not that hard. you also need to consider the features in fish that boost your productivity that don't need to be learned at all. just give it a try.
I think this is what most fish users do. I suspect that failing to understand this is possible, due to not understanding how shebang scripts are executed by the kernel, is a major reason why bash remains popular for interactive use.
It's not that. We don't want to switch shell syntax between workstation and server, for example. The fish users I've known moved very slowly when they had to hop on a server, or build a new container image where it involved a 'docker run' into the shell to test it out. If you know bash or sh well enough to do those things quickly then there is no incentive to use fish.
> If you know bash or sh well enough to do those things quickly then there is no incentive to use fish.
I honestly think you might misunderstand why a lot of people use fish. I know bash “pretty well”—I’ve written and maintained my fair share of complex bash scripts, and remain pretty comfortable opening a shell in a running docker container or EC2 instance to debug various nonsense. What makes fish attractive to me for use as my login shell is the creature comforts which are very nice to have on my regular workstation, but aren’t really necessary when mucking around in some random environment: syntax highlighting, tab completion/autosuggestion/history search which “just works”, somewhat nicer syntax for writing simple scripts for personal use, saner word splitting, and so on. I guess I can’t really speak for other fish users and am perhaps biased by learned bash first a couple decades ago, but I don’t personally find it especially burdensome to have to remember multiple shell syntaxes/semantics (I already use half a dozen in my day to day work; what’s one more?), and I view it as a reasonable price to pay for a UI I find much more pleasant on whole.
But `docker run` is the same in every shell. The only things that really change is the syntax for looping over files, advanced globing, things like that. Control-R, tab completion etc all works more or less the same with some minor quirky differences, but nothing that would slow somebody down.
Context: I used bash for about 5 years, zsh for the next 10 before switching to fish.
i use fish for interactive work and bash for scripting. if there is a script that i don't want to write in bash, then i use a real programming language like python or ruby.
I don't believe that's the goal they set out for themselves; and besides I feel like it should at least be as POSIX compatible as they could make it. They could drop POSIX oddities where they see fit, but POSIX is not all insane.
I mean, I really doubt that the `export` command is terrible somehow. In fish, you have to use `set -Ux` which is just ridiculous and petty of them, the world doesn't revolve around the fish developers and this just breaks many files that you try to source from fish; for example, Python venv activation scripts.
As for why I don't think that's their goal, just look at https://fishshell.com/ not one of the listed features requires them to drop POSIX compatibility entirely. I just want something like fish shell that isn't too radical and tries to be as POSIX compatible as possible while adding their improvements, out of the box (so ZSH doesn't count).
> As for why I don't think that's their goal, just look at https://fishshell.com/ not one of the listed features requires them to drop POSIX compatibility entirely.
I don't use fish but it does have one great feature that I'm surprised hasn't been replicated in zsh: automatic completions derived from man pages. So you get at least basic flag completions for basically every program automatically.
I used fish for a while (and really enjoyed it, it's a great shell), but it's formatting is too inconsistent with bash for me. I found myself dropping back to zsh so often to write documentation or run a playbook that I switched back.
If you often share shell code with others it may be to big of a leap for you.
I use fish since they relented and allowed to use && and || instead of ;or and ;and. Still, I always script with bash (or POSIX sh for certain things). I can't recommend that split enough. Also, I can't speak highly enough of shellcheck[1], it's a lifesaver especially when you target POSIX.
If you're running a script, you can use edc/bass to run it from a fish shell. Fisher is one of the first things I install after fish, then bass, z and a few other helper plugins.
I was hesitant to switch to fish shell, but after seeing so many recommendations on HN, I gave it a shot. Been using it for a while now, and it's mostly good.
The one hiccup is the syntax; it's different from ZSH, so you have to update your existing config. ChatGPT has been pretty useful for that, though.
At least now && works. It used to not be the case and required you to type ";and" which was incredibly annoying as you had to modify basically every single command that you found online or that people sent you.
Now that && works, I don't have any big conplaints about it anymore.
I don't know much about shells. Fish was the first one that made everything so easy and the only downside was not being posix compliant, but i can easily call bash and run the command. I tried leaving fish and the others requires so many configurations, but fish does by default. It suits me.
I may be mistaken, but since I have to work with different machines that all have bash as a shell, I try not to mess with my muscle memory and stick to bash even on my own machine. But maybe I should try Fish.
I like fish. It's good to have on my machine. I can see myself using sometimes. I'm used to bash. Bash for scripting definitely. I'm not sure what makes me look more like a "hacker" using bash, or using fish?
I don't really care, but...ha! Just wondering.
I guess fish is like, you feel like you're living in the future, but also like "this is a past that should have already been available" then you find out it has been available, for 18 years, and you wonder, "Was it me that was living in the past?"
It's the kind of thing I'm scared to get burnt on, when it fails, because I already like it. I don't want it to disappoint me, because I just feel like: "new fangled, it's always gonna break." But then, it has been around for 18 years...so...hmm.
So, I don't know. It looks pretty! I like to use it. But bash is, feels, more stable.
Worth exploring! I'm not gonna config-it, as much as possible, but for interactive shell? I think it's good! :)
Fish is pretty good, but I wish it would come with fzf-like capabilities built into it by default, for automatically searching history/files/etc.
Yes I know I can just install fzf and the fzf/fish integrations, I've done so. But my understanding is that the whole point of fish is that it comes well configured by default. fzf is a quantum leap forward for shell UX, this sort of functionality should be built in by default.
I quit fish because I missed being able to `sudo !!` to rerun the previous command with sudo. There's an alternative way to do it (something like up arrow, ctrl-i, "sudo", enter), but I can never remember it when I need it, which is not often enough to stay in my head, but often enough to be come quite annoying.
Glad to hear that's changed. There were strident statements from the developer on Github last time I researched it to the effect that implementing '!'-style history expansion was contrary to the fish philosophy and that people just need to learn the fish-y way. Looking back it, I probably could have fixed the issue for myself by setting up vi-mode in fish, but I didn't come across that option at the time.
That is a recent(-ish) addition¹, arriving in 3.1. Your interpretation of recent may be a different length to mine, but one Debian release in this instance ;)
I guess he wasn't aware. I use fish, and I'm learning this now too. I probably really should give the fish docs a read-through, as I imagine it could significantly improve my shell efficiency.
I also use `!$` (`vim script.py` and then `python !$` or `git commit !$`) but the parser rejects `!$` before it can be rewritten by the abbreviation system. [edit: https://superuser.com/a/1762626 points out that if you add a space before hitting enter then it works fine, so I'm guessing it's just a bug, and I should go with d below]
Options seem to include:
a) make a !$ replacement that is not illegal and change your muscle memory `\$` or `!\$` or `!@` or `!%`
c) some combination of a and b (e.g. make a `!\$` abbreviation and then make a binding so that if you type !$ it replaces it with `!\$` so that it gets past the parser without expliding)
d) patch the parser to allow !$ as a special case if there is an abbr for it.
I just tried b but it's pretty jarring. I think I might go with c instead.
I'm actually feeling quite positive about this now.
There is something I've been wanting to add to bash since forever, which is something to help me cd into a repo that I just cloned (e.g. `git clone https://github.com/fish-shell/fish-shell` then `cd !/` could expand to `cd fish-shell`).
Bash has a range of modifiers for history expansion. You can "cd !$:t" to execute "cd <final argument of last command, basename only>" for your git example. zsh, somewhat predictably, has a superset of bash's modifiers so it works there too.
Not to hijack, but also consider xonsh[1]. It's Python based, and all your scripts can be Python (or hybrid-Python). I've been using it for both Windows and Linux for over 5 years.
I'm interested especially for Windows, does it have any of the footguns relating to awful corporate network drive setups, $HOME, expensive prompts, and the like?
I need a good shell for when I'm forced to work on Windows machines (and when WSL isn't available). Git Bash (and even plain MSYS2 bash) performance is so unbelievably awful every single time, and the fixes can be hard to determine and a giant pain in the ass, and sometimes impossible if they are due to windows defender or whatever antivirus junk the corporate environment has installed.
However, Python runs fine, so maybe Xonsh would run fine?
I realize I should probably just use PowerShell but I strongly dislike the syntax and would have to write function wrappers for basically every command I setup. I'm sure most here can relate to that.
> does it have any of the footguns relating to awful corporate network drive setups, $HOME, expensive prompts, and the like?
Not sure what you mean - can you give an example?
There will be a $HOME environment variable.
I never use WSL, Git Bash or Cygwin stuff. Just the normal command prompt with xonsh running on top of it. So I can't speak to performance issues. If you could give examples, I may be able to address them.
Definitely should not have issues due to antivirus. It will be a program running continuously.
> I realize I should probably just use PowerShell
Powershell is probably the best, but I didn't want to expend energy learning it. With xonsh I can have the same config in Linux and Windows, and Python is always a plus.
Tried fish a couple of times, it's really good, many zsh plugins are created to replicate features of fish. But it's not my default shell, because I need to run bash shell scripts and I didn't find any way to do it in fish. So I am stuck with my slow zsh.
I often see people complain about this but I seriously don't understand. The shebang at the top of a bash script will point to bash no matter what your shell is.
At various jobs I've often seen bash scripts to set up your environment (mostly environment variables). Running a bash script with shebang will not preserve the changes to the environment variables, will it? At least that was my experience.
I use xonsh and fortunately it has source-bash for stuff like that.
Yeah I would have thought so too, but I have personally ran into this issue running fish-shell on my mac. There are some scripts I need to run that do not work even when I shebang the script to run in bash.
Yes, it really is odd, I couldn't figure it out so switched back to zsh.
The specific issue was to do with a script we had to run to gain ssh access to an internal network. I can't post the script, but it was related to openssh.
Even logging into bash and running the script didn't work, I had to remove all fish binaries, symlinks, etc and set my shell to bash/zsh. Maybe it was an issue with how I installed fish, but yeah like I said, very strange, but I can vouch that I've encountered a similar issue before
It's a real shame because I think the fish syntax alone is worth the switch, for my personal machine(s) I use it.
Edit: this was years ago now, about 4 years, maybe the issue doesn't exist anymore but it caused me a bit of grief at the time (beacuse I didn't know it was related to using fish!), I've not since tried it again. I might try again and get back to this thread
Most likely a command in your script (or one source-d into it) makes an assumption about your $SHELL or login shell that is true for bash/zsh but not for fish.
See my other comment and let me know if that script contains
ssh-agent $SHELL ...
or
exec $SHELL ...
or
eval "$SHELL ..."
or similar. :)
If it ends up passing a script file or arguments to $SHELL and you wanna fix it without rewriting it, just add some conditionals where $SHELL is used and use the equivalent flags or syntax when $SHELL indicates fish.
Alternatively, if you just wanna work around it, just launch that script like
fish doesn't have builtins but all fish commands are external binaries or fish functions. i think at one point early in the history of fish those binaries may have been installed on the global path so they were accessible outside of fish and possibly there was a name conflict with one of them that this script triggered.
although such a name conflict should not have happened (and i can't think of which command such a script might have used that would also be a fish command), and the global path thing was also fixed soonish. but this is all a faint memory, so i am not sure i remember any of that right.
- cd
- source, .
- eval
- string
- and
- or
- builtin
- command
and many others.
Not sure what the point of distinguishing between fish builtins and fish functions is; whether a builtin is shipped as a function distributed with fish or a reserved word in the fish evaluator seems like an implementation detail.
fish has grown and evolved. i was referring to this:
Builtin commands should only be created when it cannot be avoided. echo, kill, printf and time are among the commands that fish does not implement internally since they can be provided as external commands. Several other commands that are commonly implemented as builtins and can not be implemented as external commands, including type, vared, pushd and popd are implemented as shellscript functions in fish.
if i remember correctly, this led to some useful commands that are builtin elsewhere to be external binaries shipped with fish. but since those where not actually tied to the fish shell they could run without it, and if they ended up on the global path be accessible from other shells.
the relevant text on the website has been changed, but it is referenced here:
If you wanna add a builtin like that to your own distribution of fish, you could do it cleanly by keeping those binaries in /usr/lib or /usr/libexec and then wrapping them in a fish function that ships in fish's install prefix. (This is basically how fish's Python scripts for generating completions from manpages are shipped today.)
This is plausible if you have scripts that do dumb shit like
eval "$SHELL ..."
because (at least sometimes?) $SHELL is set by your login program and not your shell, and dropping to an alternative shell by just typing
zsh
and hitting enter or whatever won't reset $SHELL.
You mention elsewhere that this had to do with a special OpenSSH setup, which also fits.
One of the things you can do with ssh-agent is use it to launch a child process with a dedicated SSH agent that (only) has certain keys on it, and which exits once its child exits. This is sometimes handy for deployment scripts or doing git checkouts or whatever because you can ensure you don't get locked out for too many auth attempts because the user just has too many extraneous keys on the agent associated with their normal user session.
If you were leveraging this feature for interactive shells, you might be tempted to use $SHELL to decide what executable to have ssh-agent launch, so that you could (for example) accommodate both bash and zsh users and let them launch a shell with a special SSH agent but which honors their usual preferences by loading their usual shell and reading their usual zshenv or bashrc or whatever it is.
You mention as well that you had to actually uninstall fish to get things to work again, and also that you were on macOS. I can't be certain about the cause here, but one obvious thing occurs to me:
macOS doesn't handle environment setup like any 'normal' (Linux or *BSD) Unix. On normal Unices, your login shell actually also launches your graphical user session, so to configure a session-wide environment variable, you just set it in your shell startup somewhere. On macOS, login shells are actually only used in SSH sessions and terminal emulators. If you want to set environment variables for apps that are not launched from terminal emulators, you have to use hacks (like Doom Emacs' env file, for example) or configure them for the whole user session via a LaunchAgent.
In the case of $SHELL, that environment variable is used by editors to determine what shell to use when you run external commands. Without it, if you are a fish user and you launch MacVim or Emacs (or, presumably, VSCode or anything else) from your dock, when you go to launch external commands, they will run not in fish but some other shell (probably zsh or bash). If your install method for fish tried to handle this for you (pkgsrc and Nix don't, but the .pkg from the developers or Homebrew might, idk), or if you dropped to bash only from terminal emulator windows that were already running fish instead of opening a new session for bash, you may have wound up in a bash session where $SHELL was still set to fish. That's the only reason I can think of for why you might have had to actually uninstall fish to get this ill-behaved script to work right.
Anyway:
1. As a user, pay attention to what $SHELL is.
2. As a script author, never use `eval "$SHELL ..." or equivalent`.
> macOS doesn't handle environment setup like any 'normal' (Linux or *BSD) Unix. On normal Unices, your login shell actually also launches your graphical user session, so to configure a session-wide environment variable, you just set it in your shell startup somewhere.
That's no longer true for Linux, at least. GDM launches stuff via systemd user sessions, which do not source your profile.
I'm not sure how I feel about it. The old way feels 'simple' to me, but the new way does mean that shell misconfiguration won't hose your GUI sessions.
You don't have to translate them. Just stick `#!/usr/bin/env bash` on top. It is totally fine to use fish as your "terminal shell" and default to Bash for scripting for things like automation, etc. I've been doing this for a decade. I will also add that Fish is so good by default that I barely have any config.
Is the issue running bash shell scripts or copy-pasting one liners? If the latter, you can always use the command flag for bash to execute one liners within its own context.
bash -c "grep word file.txt | sort -u | tail"
Scripts shouldn't be an issue as long as you either launch it with the proper shell or configure the shebang correctly after making the script executable.
What do you mean? If the script is using hashbang, you can just run it. If not, run "bash script.sh". If you need to source it, use the plugin "bass". If you want to run a one-time bash command copypasted from somewhere, just type "bash", run your command, and then ctrl-c.
I asked an LLM to translate a bash script to fish once and it just changed the shebang line... cracked me up.
Edited to add:
There's a program out there for translating bash to fish called babelfish. It's pretty good but not complete, so it won't work for all scripts. Worth checking out, though:
Thanks for mentioning. I think it would help a bit if you copy-paste a short terminal session to show what VF looks like in operation. I know there are extensive docs, but a quick tldr/screenshot helps quite a bit in a README I find
Hi. I'm Ilya Sher, author of Next Generation Shell. That's the only shell that I'm aware of that plans to do something "radical" about the UI/UX. By radical I mean something out of the telegraph style communication paradigm.
I loved fish for about 5 years. My only gripe is that going back to Mac it wouldn’t play nice with the terminal color scheme, or the dark mode switch. Anyone found a way around that?
I use iTerm2 instead of the default Terminal app. In iTerm2, you can change the impossible-to-see blue and red to more reasonable values (or do what I do and use the Dracula Pro Themes).
OK so if you're new to fish you should understand universal variables since it's a concept that bash/zsh does not have and it's actually pretty great.
When people first try out fish they want to add their global env vars and PATH configuration to ~/.config/fish/config.fish. You can absolutely do this similar to how you do it in ~/.bashrc. However, it's not idiomatic and once you get used to universal variables, you'll see that it's a lot of yak shaving you really just don't need editing config.fish.
Instead, if you want to permanently set an env var across the current session and all new sessions, run: `set -Ux MY_ENV_VAR 1` (set a universal variable, and export it to subprocesses)
That will put it into a machine-readable file ~/.config/fish/fish_variables. You can open it if you want but this way you don't need to source your rc files, open a new shell, or even open your editor.
For PATH, just run: `fish_add_path ~/my-new-bin`. It uses universal variables by default.
For some reason I avoided universal variables as much as possible for years using fish and now I think that was really silly.
You can source bash files (like .bashrc) using the plugin "bass". You can also launch fish using a bash file, just export the variables and run fish as the last command.
I personally just put what path modifications I need in .profile and have fish as my login shell.
They're really completely different. Fish is mostly about having features that help you enter a command (history, error checking, completions, etc). Once you execute something, it really behaves the same as bash/zsh.
Nushell is really more about command output (my understanding, I haven't used it heavily). With Nushell you can do things like parse TOML files right in your shell:
open Cargo.toml | get package.version
Nushell understands the structure of data but fish is like bash/zsh in that it just deals with streams of text. Nushell can even interact directly with sqlite databases which is very cool.
I think if you're just looking for a simple shell that behaves a lot like bash/zsh, use fish. I think Nushell is more targeted to people that want to use its powerful data pipeline features—or are generally interested in a bigger departure from bash/zsh.
Personally I prefer fish, but I should start using Nushell more since it could definitely help with some tasks. I probably would just run Nushell when I need it though, I don't see myself running chsh to switch over.
I’ve used fish for nearly a decade now, it’s awesome.
The autocomplete works for so many things you don’t expect!
Command line arguments!
Remote path completion!
Git!
It’s something I install basically on everything machine I can. The history based autocomplete is so useful for keeping track of and refinding those less used complex commands that you have not saved in a function yet.
Am i the only one who feels fish is not worth it despite of hype? Don't get me wrong. I think that fish is really good shell.
BUT...
After adding the following plugins to zsh(before you chime in, it's just adding these lines,not anything configuring much. also it auto bootstraps on new install), I found out that fish is no where as good as configured zsh.
For example, I use fzf integration for tab completion. Fish's fzf integration is nowhere as good as that of zsh's. Also, posix compat and almost bash compat of zsh is plus.
I acknowledge that zsh isn't perfect shell either and I have tried and failed few times in past to switch to fish. If you provide me compelling reason/s to switch to fish, I am all ears.
zsh felt like it fought me every step of trying to configure it to be halfway decent. And a lot of zsh scripts out there aren’t exactly bulletproof. It shouldn’t matter, except for the fact that if you use the shell with any regularity you will inevitably bump into edge cases that weren’t handled well by a mishmash of user scripts whose provenance is mostly copy/paste with little understanding of why it is all needed.
Here’s my fish dotfiles:
https://github.com/mattgreen/dotfiles/tree/master/fish
It has a submodule based plugin system (loader in conf.d), an async git prompt, my aliases, and a few env vars set. It needs no maintenance because fish provides almost everything already.
The only thing I want from fish at this point is to make async prompts first-class. They are best handled by the shell, not user code, due to the state tracking.