Hacker News new | past | comments | ask | show | jobs | submit login
Oh My Zsh (ohmyz.sh)
159 points by praash 3 months ago | hide | past | favorite | 147 comments

Do yourself a favor and try to configure your shell without ohmyzsh first. You’d be surprised at how few plugins actually require it, and you save yourself from horrible performance.

I do myself a favor by not doing this, install ohmyzsh and start working. Seeing what other people have done with shell, vim and all sorts of things, I know this is a rabbit hole and I could spend endless time on it. That's why I use ohmyzsh, VSCode and other tools and only tweak settings when necessary. And I can be actually productive even when I get a new machine.

Performance? If you are talking about the startup performance, no it doesn't bother me. Again, nothing is slowly enough to cause noticeable delays in basic typing/editing and the bottleneck is almost never on them. (I regularly work on codebase of hundreds to thousands of files or more.) So I don't spend time worrying about saving a few seconds in total per day when I can use my brain elsewhere.

You don’t have to follow a rabbit hole, these tweaks take no time at all and you can stop whenever. I used Oh My Zsh until I got fed up with the startup slowness. I open a bunch of terminal windows during the day and every one of them had a second or two of delay before I could do anything. I decided to do myself a favour and no longer put up with it. It took me a handful of minutes to figure out which plugins I actually cared about (three) and get rid of Oh My Zsh entirely. Everything about this change is better for me: it’s easier and faster to redo the setup when I do a clean install, and it’s instant in everyday use which means it’s no longer frustrating.

I heard a lot about slowness of oh-my-zsh but never experienced it myself.

I had slow starts when I added nvm completion to .zshrc and .. maybe conda environment but that was unrelated to oh-my-zsh

I've also not experienced any slowness with oh-my-zsh. Now LunarVim, which is an IDE-like layer for Neovim...that's a totally different story.

Hmm? What about LunarVim?

If you add more than a handful of plugins in any of these IDE layers for Neovim, like LunarVim, LazyVim, AstroNvim, &c., it can slow things down to an unacceptable level quickly.

That really depends. On the iTerm2 terminal? Yes, sometimes. On Alacritty and Rio? Nope, it's very snappy.

No need to rely on your terminal to provide performance. LunarVim is very slow even though I use Alacritty, it was the main reason I stopped using it and switched to LazyVim.

If I'm being quite honest, I think LazyVim is the more polished project. I may end up switching to that; I've been impressed by what I've seen so far (as well as using the lazy.nvim package manager).

Some plugins can make it crawl, yes.

'Wansmer/symbol-usage.nvim' is one of them. I found that I didn't really need it as much so disabled it and LunarVim became much snappier.

Yes, should have qualified it a little more by adding that it does depend very much on which plugins are currently loaded.

> I heard a lot about slowness of oh-my-zsh but never experienced it myself.

This was years ago, no idea how it is today. But I also have no reason to go back.

> I had slow starts when I added nvm completion to .zshrc

That too, but that’s unrelated. To me that was yet another reason to stop using node altogether, I wasn’t enjoying it anyway.

PowerLevel10k has quite a bit of functionality, and is more performant in my experience, giving me the best of both worlds.


While I love p10k and use it myself, note that p10k is just a theme, while ohmyzsh is a theme manager (that comes with default themes) + plugin manager + a collection of aliases + other QoL stuff.

p10k is not just a theme, it implements a whole prompt to realize features like instant and transient prompt. For example showing your current Kubernetes namespace while you are typing a kubectl command.

Having PowerLevel10k shortened as p10k bugs me, because "owerLevel10" is 11 characters.

Yeah I have a ton of customization including a really sweet looking prompt (that includes branch name & even git remote project name). Shortcut aliases and custom functions for everything that I use often. Atuin for Ctrl+R history searching.

All without using any “plugins” or ohmyzsh. All just within my .zshrc, and a few extra files that get “sourced” depending which computer I’m on. Only occasional copy-pasting a few things I liked from StackOverflow.

Basically instantaneous speed. Don’t even notice any performance penalties from all of the customization and styling.

I did have a performance issue early on, but I profiled my zsh startup time and saw 97.5% of my shell startup was consumed by NVM (node version manager), and another 2.4% was RVM (ruby). Switched to FNM and Chruby instead, and it was zippy.

And it’s all mine, so there are no “updates” to break anything. Throw it all in source control and you can keep improving it without risk of losing your previous working config.

Customizing my prompt was a reason to stick to zsh instead of oh-my-zsh.

But lately I've become really happy with just installing spaceship.

Sure, it doesn't look exactly like I want it to. But it shows git status.

Various features just "pop up" if I install the right things on the system.

starship is the new spaceship, yo


Yep, I use zsh with 2 plugins. One for syntax highlighting commands and another for showing auto-suggestions. It's really fast. The rest is nearly a default zsh set up in terms of zsh configuration. Everything is documented in my dotfiles https://github.com/nickjj/dotfiles.

My prompt is a 1 liner that shows your git branch as well as coloring up $ to be red or not based on if the last command failed. Coincidentally I just released a blog post today on coloring up your prompt based on if the last command failed at https://nickjanetakis.com/blog/color-your-shell-prompt-red-i... , there's solutions for both zsh and bash.

Noting that you didn't solicit advice, but…

* Exporting shell variables such as HISTFILE isn't necessary, and can be unsafe. For example, if you decide to pop open unconfigured bash from within a zsh session it would intermingle its history on write.

* There is a smart keyboard subsystem that neatly manages terminal differences¹, making it much nicer compared to inserting {system,term}-specific escapes in to your config.

Hoping this comes across in the helpful spirit it was intended, not as nitpicky unwanted code review.

¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

Thanks, I'm always open for advice.

* For shell history I don't think I've encountered that issue yet. For example if I have zsh loaded and run `bash` and then within that bash session run `whoami` and exit bash, my `history` within zsh doesn't include the whoami command, only `bash`. Is there another workflow that would produce intermingled history?

* Ah, this is likely in reference to the home / end / insert / etc. key binds I added? I think I came up with those from following a 2007 blog post[0] which I found here[1]. Do you know what the nicer versions would be for those specific keys? The docs are coming up empty with specific examples and most Google results return the escaped references.

[0]: https://blog.andrewbeacock.com/2007/08/how-to-get-home-end-k...

[1]: https://stackoverflow.com/questions/8638012/fix-key-settings...

For the first; Unless your bash config overrides the environment variable you've set it will use $HISTFILE from the calling shell, which is why "HISTFILE=<location>" without the export fixes it. You can test it with:

    export HISTFILE=trash
    bash --norc
    echo hello
    cat trash
It isn't just intermingling either, bash may truncate the file depending on how it is configured too. You can see this by performing the same procedure as above but starting with 1000 lines in the trash file, bash will truncate the file to 500 lines by default on exit. It shouldn't happen in your case as you're also exporting HISTSIZE, but it can if you have a lot of multiline history events as bash treats them differently to zsh.

The point wasn't just about HISTFILE really though, very few of the shells own configuration variables are useful in child processes. (LC_* and PATH being the obvious exceptions that spring to mind.)


For the second; The doc I linked to above shows how to use zkbd to handle terminal differences in a clean way. Run the wizard, and then you can use the $key array as in $key[Home]. The neat thing to do with zkbd is have the wizard run on startup when it can't find its definitions file, that way you'll get correct behaviour whenever you play with a new terminal type.

Another option is to use the terminfo database¹ directly, if you trust it to be correct for your terminals. "zmodload terminfo", and then the database is available through the $terminfo array as in $terminfo[khome] or using the echoti function².

¹ https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#The-...

² terminfo(5) contains the mappings, but they're often far less readable than the $key array. $terminfo[kpp] vs $key[PageUp], for example.

Thanks, I'll test them out and apply the changes. It sounds like all 4 of the history env vars don't need to be exported.

What felt like an initial thirty second throwaway comment yesterday has turned in to a pile of replies that feel like a poorly conceived Ted talk now, forgive me for that.

The dividing line between variables that should be prefixed by export are ones that are generally useful to child processes and ones that are not.

For example, $PATH is useful and should be exported. You probably want scripts you start to have access to all the things you have installed, not just the locations of the default search path:

    PATH= =zsh -fc 'print -l $path'
$HISTFILE/$PROMPT/etc control current shell behaviour and are unlikely to be of any use to child processes executed by the shell, and do not need to be exported. Remembering, of course, that they'll be set by any new interactive shells anyway as they too will read their startup files when launched.

Oftentimes it doesn't make much difference. However, some such as $CDPATH can cause non-obvious bugs when they're exported, and some such as $HISTFILE can cause data corruption or even loss when the planets align against you.

Hah no problem.

There was just enough time after your talk for 1 more question from the audience:

For my zshrc that you poked around in, is this issue related specifically to HISTFILE or all of the history related env vars?

All four of the $HIST* parameters are perfectly functional without export.

Someone's made a benchmarking system for zsh: https://github.com/romkatv/zsh-bench#premade-configs

Of course, their config is the best according to the benchmark (and ohmyzsh is the slowest option), but DIY configs are also covered, particularly possible performance optimizations.

100%. This is dotfiles on super easy mode. PS1 and PROMPT_COMMAND are your friends!

I hate very few things, but PS1 is one of them.

Would recommend using a PS1 generator, e.g. [1].

[1] https://bash-prompt-generator.org/

Nobody is friends with PS1.

Just pull down the extensions from the source repo and source them in your zshrc.

I used ohmyzsh with powerlevel10k/powerlevel10k[0] for years though recently i've settled on fish [1]

[0] https://github.com/romkatv/powerlevel10k [1] https://fishshell.com/

Yeah I tried zsh a few times and never really thought it gave me that much relative to my existing bash config.

Fish on the other hand has stuck, and I'm still discovering nifty new built in features, like the fact that if you type `kill`, you can tab-complete on process names, so like if I want to kill emacs, I can type `kill ema<tab>` and select from the following:

    > kill ema
    3296  (.blueman-applet)  3595  (.blueman-tray-w)  9324  (emacsclient)  9327  (emacs)  9557  (emacsql-sqlite)
If there's only one match it completes the PID for you, and of course if you start typing a PID and press tab it shows the process names along with the potential completions.

I use starship for prompt customization, which is nice because my config transfers just fine from bash over to fish.

FWIW, that is also the default behaviour of zsh's standard completion subsystem for kill. You can try it yourself: "zsh -f" to get a shell without reading a fancy config, start compinit, "kill <Tab>".

You can even disable verbose mode via zstyle, should you be the type of person that likes a simple pid list like bash's completion project provides. To me this level of customization is the main feature zsh provides, but not everyone incessantly turns every knob they see.

Nice! It's super useful in fish, good to know it's in zsh too

What I do is use zsh as my default shell and use oh-my-zsh, but keep a very simple config for my ~/.bashrc, something like:

    [ -f ~/.fzf.bash ] && source ~/.fzf.bash

    source /Users/wyclif/.config/broot/launcher/bash/br
This gives me the best of both worlds.

I start using fish, really like its feature set, but then have to give up and switch back to zsh when I want to get anything done. Unlike zsh, Fish isn't compatible with bash syntax, so a lot of existing scripts and software just doesn't work right. Even today people write scripts as if bash already exists and they seem to always target it. I wish fish had some form of compatibility layer.

Are sourcing bash scripts in a fish shell? If you can either run bash ./xyz or add the shebang #!/bin/bash to run scripts with the intended interpreter

I've been using it for years and most things I need nowadays just work (i.e. have Fish support out of the box).

For all the rest, perhaps give https://github.com/edc/bass a try.

Can you add a shebang and make the script executable or just run the script as an argument to the bash program?

This . You just have to use fish for live interacting with the system aaand its great ,for everything else you can stick to bash.

Don't even change your default shell with chsh ,rather just point your terminal emulator to launch fish

I recreated my zsh setup in fish with about 10% of the config and just one plugin (fzf.fish).

Nearly everything I want, fancy autocompletion, syntax highlighting, git-aware prompt just worked out of the box.

Fish runs bash scripts just fine, as it does any script with a shebang line. IT is increasingly compatible with random CLI commands copy and pasted from the internet.

For those that don't work right away, just type `bash` to enter bash shell, run the command return back to Fish.

If a significant part of your day is spent copying CLI command from the internet, then yes, perhaps Bash is a better choice for you.

fish has a compatibility layer, and existing scripts still can use bash

Can you summarize what made the switch worthwhile for you?

I've been using zsh/omz with a customized powerlevel10k for years now and I see fish mentioned all the time but I didn't really find a compelling reason to try it out for myself.

My niche use case is that since fish comes out of the box with a whole bunch of very nice features (syntax highlighting on the shell, really good autocompletion) it's easy for me to stick it into the set of shell scripts I use to turn a new Ubuntu VM into a dev productivity machine. [1]

I could probably get Zsh to do all the same stuff I would want fish to do out of the box, but it would make reading through and reasoning about the shell scripts more difficult for third parties to audit, who may not be familiar with either tool before they try it.

[1]: https://github.com/hiAndrewQuinn/shell-bling-ubuntu

You just install it and it works. I change devices, or wipe out my devices often enough that just having a familiar shell installed in one line feels comfy. I usually don't customize things a lot, I pick something with good default and rarely change anything on it. I don't want to bother downloading plugins and addons, or fonts, or themes, just for a command interpreter.

For me it came down to speed and maintenance. Fish is incredibly fast and I spend almost no time configuring it, so it’s trivial to bring up on a new system and I don’t have to exercise self-control to avoid tweaking it (that’s a personal failing, not other shells).

It's easy to install. I used to have some fisher plugins, but gave up on those since none of them were really essential.

When I set up a new computer I can just install fish and starship prompt and I'm mostly done. My fish configuration file is just aliasing and sourcing configs from other software, it's been a while since I had to touch it.

only a few things that are probally also possible in zsh

fish functions are super easy to create on the fly from a command updating $path is fish_add_path {path here} setting global variable is easy set -Ux FOO bar adding -g makes it global

most of these require me to update my .zshrc and source ~/.zshrc as far as i am aware

fish has by far the best auto-completion out of the box. That’s what sold me.

And the website is amazing. “Finally, a command line shell for the 90s”

Tide is as close to powerlevel10k as one can get in Fish.


zsh, oh-my-zsh, p10k, fzf, and as of recently zsh-autosuggestions plugin for oh-my-zsh is what I ride on. I keep hearing about fish, and I see what it's doing but I'm not sure what it would bring to the table compared to the setup?

So fish comes with nice defaults. It could happen that you have a complicated zsh setup, then migrate to fish and you find the defaults are fine.

The fish scripting language is nicer (more logical) than the zsh one. That's because zsh needs to be Bourne-ish for historical reasons, and fish has decided to deviate from it. Existing sh, bash, zsh scripts will continue to work just fine. You can write new scripts in fish, or keep writing scripts in zsh or whatever.

I never understood how omz was useful.

Zsh already has a module system (autoload), a prompt framework (promptinit), and Git integration (vcs_info) builtin.

I have a pretty extensive Zsh setup in vanilla Zsh: https://github.com/cbarrick/dotfiles

You're correct: omz adds not a lot to vanilla zsh.

It consists of: - collection of plugins/themes - auto update - way to customize them

Everything could be done directly in .zshrc, it's just a bit more convinient

I used zsh for a few years before oh-my-zsh became a thing.

I have to admit that I don't find it more convenient.

It takes an ecosystem where things have a way of working, and establishes new conventions on top of those using a new set of environment variables. So if you know zsh, you don't know oh-my-zsh.

A vanilla zsh will feel very bare.

A vanilla oh-my-zsh will feel very feature rich.

If you end up configuring zsh anyways, I don't see the point at all.

Recently, I moved off from oh-my-zsh after many users, to vanilla zsh with https://starship.rs, mainly due to the loading speed (used https://github.com/romkatv/zsh-bench to measure the speed).

Still wanting to try out fish and hopefully soon!

If one of a product's main features is that it's written in Rust, it probably doesn't have anything unique compared to the competition

Which is a major selling point. We do not want anything unique.

Ripgrep accept most basic flags that grep uses and is way faster (when searching for code under VC), and that makes using it very convenient, even before considering the features on top.

I would prefer that you also write your HN comments in Rust, if that's possible, for better performance and safety. In the future, there will only be Rust. You have to accept Rust into your life.

A memory-safe, fearlessly concurrent version of $thing is imho a huge win in and of itself.

Soon a Rust userland will be table stakes.

Fish has been great for years.The Rust rewrite will help the devs catch issues earlier in development. Hardly a main a feature.

The awesome level tab-completion and auto-completion are the firs things to notice about Fish. Also, overall cleaner syntax and a several nice built-in commands that don't ship with Bash.

Not sure if you're talking about starship or fish, but starship is by far my favorite prompt customization tool, regardless of what language it's written in. It works across bash, zsh, fish, and others, so you can pretty easily get the same prompt in any shell on your system. It's easy to tweak as needed, but is pretty great out of the box.

Moving to starship as prompt stopped my prompt bikeshedding habits immediately.

All good until your ZSH gets heavyweight and slow. Started using fish and never looked back

I've never noticed slowness in OMZ, or really any shell. Or at least, when something feels slow I've always assumed it's the application I'm using, or network congestion, not the shell itself. In what situations do you notice a shell being slow?

Initializing a new session is not instantaneous. Even on my M3 Max it probably takes a couple hundred milliseconds, which is fine.

When I first tried it over a decade back, IIRC on an 11" Air, each new session was probably closer to a couple seconds. I recall there were a couple plugins in particular that were major bottlenecks. Replaced those and got the init speed to about half that but it annoyed me enough to do a clean zsh setup.

OMZ is fast even on my phone.

It turned slow for a whole after I installed anaconda. If you use conda and your shell is slow, try commenting out the code that loads conda, because it's probably that.

nvm likes to slow things down too. Not as bad as conda, but I did add some code to delay load it.

Do you know how fish would prevent getting slowed down by external scripts in its configuration file? Or does it just not support those scripts perhaps?

I switched from nvm to fnm a few years ago and have never looked back. Zero performance issues and it supports .nvmrc files.


It's wild to me how slow conda is. Just in ordinary day to day use, with nothing weird, you sometimes need to wait insane amounts of time, even on incredibly fast systems. Whatever they're doing, it's wrong and bad.

I had exactly same experience: nvm and conda. Both are unrelated to oh-my-zsh completely: they were configured in .zshrc directly

I just skipped over zsh since I didn't want to spend time configuring it, as fish is pretty good out of the box.

Ditto. Added atuin.

ZSH + Zimfw + Powerlevel10k is probably the fastest "bling"-y shell I managed to put together. Would usually smoke Fish, but I haven't compared recently

I backtracked all the way to Bash. Because I seem to write some amounts of bash scripts, it seems living inside bash is helpful. And it's really not much I feel like I am missing in my use from zsh (or fish). Bash even supports CTRL+R for history with search nowadays.

I write bash scripts but use Fish interactively.

Yes, I've had to get clear where they differ, but the Fish experience is that much better that it seems worth it.

I've considered replacing more my bash scripts with Fish scripts, but it seems Fish has a slower start start-up time for scripting (not that it matters most of the time) and is more designed for interactive use.

I only script in fish anymore, all my devices use fish anyway (it's even pre-installed on steam deck).

Started using fish, moved back in 3 minutes. Remembered I have this awesome shortcut in Zsh where I type what I need to do, hit cmd+G, and some ChatGPT replaces my input with an example command.

oooh, what plugin is this?

My only issue with fish is that it has had a standing issue[1] for over 12 years where functions and blocks cannot be backgrounded. This makes backgrounding a series of commands in a script nearly impossible.

[1]: https://github.com/fish-shell/fish-shell/issues/238

Came here to say this. Fish shell is such a fresh beeeze compared to zsh.

Now it’s even rewritten in Rust!

You've got to install Fisher, then get z, sponge and a few others from the awsm.fish list.

Then you get trapped by the utility and struggle when you land on some remote server's bash shell.



The defaults it ships out of the box makes the shell actually usable. Unsure I could ever go back to a regular bash/zsh prompt.

A lot of people will tell you this is slow and you've got to use X,Y,Z instead. If you're new, I'd strongly recommend just sticking with this, it's much easier to configure.

The following goes a long way:

    setopt PROMPT_SUBST
    PROMPT='%B%(?..%F{red}%?%f )%F{blue}%~ %F{green}%#%f%b '
    RPROMPT='%B%F{red}$(git branch --show-current 2> /dev/null)%f%b'
And if you want autosuggestions:

    brew install zsh-autosuggestions
Then add the following to your ~/.zshrc:

    source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh

Hey, I must have copied something similar from somewhere but yes my first base setup of my shell is

  PROMPT='%{%F{red}%}%~ %{%F{yellow}%}% › %{%F{reset_color}%}%'
Anything after (besides the path and the GPG setup) that is an add-on that I can remove and still function well. I've learned to live without Git info. But this is very personal and I have not been into active development for quite a while.

PSA: simply installing this won't get you many benefits until you read about what it can do and then make an effort to use those things in your workflow.

Any recommended reading? I found a cheatsheet [1] which seems useful, but there's not that much in there.

1. https://github.com/ohmyzsh/ohmyzsh/wiki/Cheatsheet

Zsh autosuggestions Zsh syntax highlighting Fzf-tab

Paired with zoxide and fzf for the zsh keyboard shortcuts are all I need to be very productive.

Starship.rs is very useful as well as a theme but pure and pl10k are also great.

I use and like omyzsh, but find it super annoying how it deals with updating. It either nags you constantly to update, or if you set it to "auto," then it's constantly spamming you about how it's updating, and when you create a new shell session (say, in tmux), it causes significant lag before you can use the new shell and pollutes the console with tons of output. There has to be a better way, like some optional mode that just runs an update service in 3am silently using systemd.

Grml zsh is all I need https://grml.org/zsh/

grml is great! It has pretty much everything you need. grml config file is also quite readable and you can learn quite a lot from just reading it.

I actually never used the live bootable cd of the grml project, just the zsh config

For comparison, here is my Zsh configuration in NixOS:

    programs.starship = {
      enable = true;

    programs.zsh = {
      enable = true;
      enableCompletion = true;
      enableBashCompletion = true;
      enableGlobalCompInit = true;
      syntaxHighlighting.enable = true;
      syntaxHighlighting.highlighters = [ "main" "brackets" ];

      histSize = 100000;

      # See `man zshoptions` for more details.
      setOptions = [
        # Remove duplicates continuously from command history (preserve newest entry).

        # Instantly share command history between all active shells.

        # Disable ^S and ^Z for less accidental freezing.

        # Save timestamp and duration of each command in command history.

      shellAliases = {
        rm = "rm -iv";
        ls = "ls -F --color=auto";
        gs = "git status";
        gd = "git diff";
        gdc = "git diff --cached";
        gap = "git add -p";
        gl = "git log";
        gpr = "git pull --rebase";

      interactiveShellInit = ''
        bindkey '^[[7~' beginning-of-line
        bindkey '^[[8~' end-of-line

        bindkey '^R' history-incremental-search-backward

        eval "$(starship init zsh)"
My .zshrc used to be bigger, but I've slimmed it down to see what I actually use from it.

One time, I was cowboy coding and ended up writing `grhh` (`git reset --hard`) and hit enter before I realized that it was a mistake.

Reflog to the rescue: https://git-scm.com/docs/git-reflog

Zprezto is a good alternative which is also faster. I eventually migrated to zim because of its minimalist approach.

I think starting from Oh My Zsh or zprezto can be a good choice. Once you get a feel of what zsh can accomplish, eventually probably you’ll one day find it too slow and/or too complicated and then would switch to something like zim to only load the things you know is useful from then.

Do yourself a favour and install fish-shell with starship.rs and call it a day. Make sure to put everything prompt related in a `if status --is-interactive` block. Blazing fast versatile fancy prompt and interactive human friendly shell. What does a man need more?

I followed this advice and my shell went from 1530ms to 35ms startup time.

Main culprits were language switchers (nvm, jabba, pyenv). Which I moved to lazy loading.

If I drop the ohmyzsh plugins startup time is 11ms. But, I want some quality of life.

There's a nice benchmarking command in the article if you want to test yours:

for i in $(seq 1 10); do /usr/bin/time $SHELL -i -c exit; done

That benchmark command isn’t great: https://github.com/romkatv/zsh-bench#how-not-to-benchmark

I prefer sheldon[1] for the few plugins I use

[1] https://github.com/rossmacarthur/sheldon

I use omz primarily with the Kubernetes addons - which are now integral to my existence.

Does fish support something similar? If so then I could be encouraged to give it a whirl.

zsh autosuggestions has been pretty slow for me compared to fish out of the box, switched a year or so back and have been pretty happy. maybe something has changed now :thinking-emoji:

oh-my-fish is pretty much similar in capabilities and has a good assortment of themes.

All I used that came with zsh were git shortcuts like gc -m "comment", gst for git status which i just recreated in my fish config.

These days I stick to a minimal profile for the default shell (zsh on macOS and bash on Linux), adding no further than some aliases. When I need more “friendly” interactive features I launch fish which is… friendly and interactive, and exit when I’m done. Thus I get the best of both worlds.

I'm a developer of 10 years, and use the command line for Git, Brew and a few other things, though I'm normally an IDE developer. I believe the CL is as powerful as everyone says, but what are some useful things I can use it for? I use Zsh on a Mac some of the time.

"Always Bet on Text"

- CLI encourages automation (shell commands are easier to repeat/parametrize then GUI steps) - shell instructions are more git friendly than screenshots (even if a process can't/shouldn't be automated. Commands are easier to document in a reusable/updatable way) - CLI can be used to run tests in a way similar how CI does it (more reproducible)

Command line tools are easier to extend/combine with existing pipelines (rg,jq,xargs): read input from stdin/write output to stdout, report on stderr, return non-zero code on error. It enables you to create adhoc tools that you wouldn't bother otherwise (unrelated: LLMs also have this property by making your skill set much broader (though very shallow with current LLMs)). Shell also has Forth-like property (compose with: retry, timeout, setuid, exec, xargs, env, ssh, etc) https://www.oilshell.org/blog/2017/01/13.html

Rename hundreds of files at a time. Find stupid errors in GB sized csv/json/.. data files. Automate git bisect. Automate workflows by writing a short loop or 3 commands in a row you can easily repeat. Down/upload big datasets. Convert text files any way you can think of.

The two things you can do in the shell you mostly can’t do elsewhere is compose arbitrary commands and store custom commands.

For #1 this blog post has some good examples of quickly chaining together commands (though personally I rarely use xargs) https://drewdevault.com/2020/12/12/Shell-literacy.html

For #2 once you’ve got a command you like, maybe one that generates a metric, you can now re-run it with ease from your history, saved text file, or an alias. You could also share it with teammates.

Please correct me if there are other ways to achieve the above, shell is the only way I know

Programming languages REPL environments.

Colorful prompt with context information, powerline glyphs, autocomplete, command highlighting, easy navigation through strings, plugins and a plugin ecosystem that extends your shell like crazy

> but what are some useful things I can use it for?

I mean, surely you already know?

Anything where feeding input between different tasks, or where you want to use regex, or similar things the cl will be superior.

10 years in tech and you haven’t optimised your shell?

20+ years in tech and these days, the first thing that comes to my mind is usually, “Can I walk out of this?” :-)

The idea is to be able to use any computer/system/devices easily instead of one perfectly.

I strive to speak multiple languages, but I think it still worthwhile to be really good at my primary language of English.

Same with computers and servers. I interact with a lot of them, but my primary computer that I use >80% of the time is worthwhile to optimize with some tooling that's not available on all the others.

Gosh, I couldn’t think of anything worse than having to optimise myself for generalist systems

Might be a generational thing.

Some folks grew up on systems that could fail at any time and leave them with nothing but the tools in /sbin to fix it with. No /usr, no bash/zsh, just sh and vi if you were lucky. You learn to love the cool new things, but you still have a mental bag packed with fsck and ed in case you need to bug out.

It's silly, really because no systems are like that any more, but the things you learned at 2am when you were 22 tend to stick with you.

Perhaps, I’ve been in tech 18+ years though. Cut my teeth on Solaris, AIX, Unix, Linux etc… the good old days!

Coding since 1986 and I touch the shell as much as I have to, If I cared that much I would still be using MS-DOS, and UNIX without X.

When you need to rename 5000 files from abcd_small.jpg to abcd.jpg, how do you do that?

  rename s/_small// *_small.jpg
When you have the string ABCD_XYZ in 50 files but you need to change it to DEFG_UVW, how do you do that?

  perl -pi -e 's{ABCD_XYZ}{DEFG_UVW}' **/*(.)
When you need to move all the files ending '.png' into the directory 'PNG', and all the ones ending '.jpg' into 'JPG', how do you do that?

  mkdir JPG PNG;
  for i in *.png *.jpg; mv $i $i:e:u

As we're in a zsh story, I'll point out it comes with a clever file renaming interface out of the box¹. It allows full access to all the advanced glob operators zsh provides too².

¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

² https://zsh.sourceforge.io/Doc/Release/Expansion.html#Filena...

On the second one - if that’s in code than a good IDE will not only do it with a single keypress, but will also (optionally) do it intelligently eg change only in the code, not the comments, show you a browseable preview, and offer undo should you get it wrong.

I like the shell but I also think IDEs are underrated.

There are GUI tools that do that, and thankfully most scripting languages have a REPL.

I'll bet it takes longer to find and use a GUI tool for these.

And a shell is a REPL.

You bet wrong, because naturally approaching 50y, I have my tools for quite some time, for the stuff I care about, not random examples on the Internet.

A UNIX shell is a very bad approximation of a real programming language REPL.

It is no accident that sh scripts turn into Perl, Python, Tcl, Lisp,... when one wants to keep sanity.

X years in tech and you haven't Y.

Pick any X and Y that maximises your ability to feel superior, I suppose.

Nothing to do with being superior (seriously - it’s just a shell?) - was just surprised (if that’s ok with you).

Honestly, fair enough. I probably misread your tone!

No worries, it happens and could have just as easily been how I worded it. :)

Been using it for years now, can't fault it, but I don't do too much with it

I would actually recommend using fish with budspencer theme which is really great https://github.com/oh-my-fish/theme-budspencer

Loading time is not an issue for me. I run tmux so my sessions stay alive and performance is very quick. M2 MacBook Air with 16GB RAM, using Warp terminal. Using OMZ with Dracula Theme and mosh for remote servers.

Am I the only one with almost nothing custom in my bash/zsh?

I don't either. -hell, since I found out that "set -o emacs" gives me history and autocompletion I go even further and usually only use /bin/sh on NetBSD.

I'm not sure what the use case for zsh and fish are, but I'm guessing it's different than mine.

(edit/update: apparently, judging by a quicky netbsd 10 vm install, you don't even need to explicitly "set -o emacs". /bin/sh does it by default)

No, I've used vanilla Bash for two decades now. The only thing I change is make autocomplete not case sensitive, and set up an ls alias

    alias ll='ls -lvX --almost-all --group-directories-first --human-readable'
I can sit at any machine and feel right at home.

I add in a folder to my path where I keep scripts I wrote, that’s about it.

OMZ and zsh are great in many ways, but I still miss my CTRL + W from the bash, deleting the whole word regardless of the chars...

Like practically everything zsh, it can be configured. The select-word-style zle widget¹ ships with zsh, and has a bash compatible setting(among others). The interface is super powerful, and given that you can change it in individual zle widgets you can make it context aware if you wish too.

¹ https://zsh.sourceforge.io/Doc/Release/User-Contributions.ht...

works perfectly fine for me. maybe you have misconfigured your terminal application?

funny coincidence, just finished re-modding my zsh.

Removing omz, adding antidote and starship. feels (and measureably is) faster and snappier.

One neat alternative is ohmyposh.dev

One option I really like liquid prompt[0]. Simple design which just shows the info I need without getting on my way

[0] https://github.com/liquidprompt/liquidprompt

ohmyposh is a prompt theming engine, not a plugin manager. But it is a great way to find a good prompt or create your own.

Note that most of ohmyzsh can be done in pure Bash

Just use fish.


Are you ok man?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact