47 votes

The Modern CLI Renaissance

19 comments

  1. [3]
    Toric
    Link
    This is by far the longest thing Ive ever written on my blog (both in length and time it took me to write!), and the first thing that I feel pretty proud of. Previous entries have more or less...

    This is by far the longest thing Ive ever written on my blog (both in length and time it took me to write!), and the first thing that I feel pretty proud of. Previous entries have more or less been writing about something Ive done, this is about a broader thing Ive observed in the linux community.

    Id love to hear what people think of this. I dont write a huge amount, and this took me almost 6 months to write according to git log, so I apologize if its a bit disjointed.

    22 votes
    1. [2]
      Boojum
      (edited )
      Link Parent
      One omission that jumped out at me is that you have Silver Searcher and Ripgrep, but not ack which inspired that whole line of modern grep replacements. It's written in Perl and was first released...

      One omission that jumped out at me is that you have Silver Searcher and Ripgrep, but not ack which inspired that whole line of modern grep replacements. It's written in Perl and was first released in 2005.

      Both of the other tools acknowledge their inspiration from ack:

      The Silver Searcher

      A code searching tool similar to ack, with a focus on speed.

      [...]

      • Ack - Better than grep. Without Ack, Ag would not exist.

      and

      ripgrep (rg)

      [...] ripgrep is similar to other popular search tools like The Silver Searcher, ack and grep.

      8 votes
      1. Toric
        Link Parent
        Good point, I was mostly focusing on them as grep replacements, probably because I still havent learned ack. (also, I had no idea ack was so new!)

        Good point, I was mostly focusing on them as grep replacements, probably because I still havent learned ack. (also, I had no idea ack was so new!)

        6 votes
  2. [5]
    Minori
    Link
    I deeply hate CLIs, but perhaps many of my issues are I don't know what or how I should configure things. I don't want to spend forever tinkering. I just want to get things done and see all the...

    I deeply hate CLIs, but perhaps many of my issues are I don't know what or how I should configure things. I don't want to spend forever tinkering. I just want to get things done and see all the information I need. I use zsh as it came default for my system; I'll probably give Fish a try.

    6 votes
    1. Toric
      Link Parent
      Thats too bad, I love CLIs more than GUIs to the point of seeking out CLI tools over their GUI equivalents. Though I agree that older CLIs dont exactly have a reputation for being new-user friendly.

      Thats too bad, I love CLIs more than GUIs to the point of seeking out CLI tools over their GUI equivalents. Though I agree that older CLIs dont exactly have a reputation for being new-user friendly.

      12 votes
    2. hungariantoast
      (edited )
      Link Parent
      If you're just using vanilla Bash or Zsh then yeah, the command-line is painful to use. Thankfully, Zsh has a ton of frameworks and plugins you can add to it that make the experience so much...

      If you're just using vanilla Bash or Zsh then yeah, the command-line is painful to use.

      Thankfully, Zsh has a ton of frameworks and plugins you can add to it that make the experience so much better. These are the ones I use:

      I've been using these for half a decade (at least) and they've been stable. I don't remember how much time it took to configure everything, because it was years ago and I haven't touched it since. I think that speaks for itself regarding whether it was worth the time invested.

      And because I haven't messed with configuring those plugins in years, I'm not sure if my .zshrc is still the recommended way to set things up (and it's a huge mess that I really ought to clean up), but here are (I think) all of the relevant lines for these plugins from my config:

      if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
        source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
      fi
      export ZSH="$HOME/.oh-my-zsh"
      export FZF_DEFAULT_COMMAND="find . -not -path '*/\.git/*' -printf '%P\\n'"
      export FZF_DEFAULT_OPTS="-m --height 100% --layout=reverse --border --color=16 --preview='bat --style=numbers --color=always {}'" # This line requires bat: https://github.com/sharkdp/bat
      export ZSHZ_DATA="$HOME/.config/zshz/z"
      zstyle ':fzf-tab:*' fzf-flags -m --height 100% --layout=reverse --border --color=16 --preview='bat --style=numbers --color=always {}'
      ZSH_THEME="powerlevel10k/powerlevel10k"
      POWERLEVEL9K_PROMPT_ON_NEWLINE=false
      POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(host dir status dir_writable vcs)
      POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=()
      POWERLEVEL9K_HOST_LOCAL_FOREGROUND="000"
      POWERLEVEL9K_HOST_LOCAL_BACKGROUND="255"
      POWERLEVEL9K_DIR_HOME_BACKGROUND="005"
      POWERLEVEL9K_DIR_HOME_FOREGROUND="000"
      POWERLEVEL9K_DIR_HOME_SUBFOLDER_BACKGROUND="004"
      POWERLEVEL9K_DIR_HOME_SUBFOLDER_FOREGROUND="000"
      POWERLEVEL9K_DIR_DEFAULT_BACKGROUND="001"
      POWERLEVEL9K_DIR_DEFAULT_FOREGROUND="000"
      POWERLEVEL9K_DIR_ETC_BACKGROUND="003"
      POWERLEVEL9K_DIR_ETC_FOREGROUND="000"
      POWERLEVEL9K_DIR_PATH_HIGHLIGHT_FOREGROUND="000"
      POWERLEVEL9K_DIR_PATH_HIGHLIGHT_BOLD=true
      POWERLEVEL9K_DIR_PATH_SEPARATOR_FOREGROUND="000"
      POWERLEVEL9K_VCS_CLEAN_FOREGROUND="000"
      POWERLEVEL9K_VCS_CLEAN_BACKGROUND="002"
      POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND="000"
      POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND="003"
      POWERLEVEL9K_VCS_MODIFIED_FOREGROUND="000"
      POWERLEVEL9K_VCS_MODIFIED_BACKGROUND="009"
      DISABLE_AUTO_UPDATE="true"
      COMPLETION_WAITING_DOTS="true"
      HIST_STAMPS="yyyy/mm/dd"
      fpath=($HOME/.config/zsh/completion $fpath)
      autoload -Uz compinit && compinit -i
      plugins=(
        copybuffer
        fzf-tab
        colored-man-pages
        git
        history-substring-search
        web-search
        zsh-autopair
        zsh-autosuggestions
        zsh-completions
        zsh-syntax-highlighting
        zsh-z
      )
      source $ZSH/oh-my-zsh.sh
      source $HOME/.oh-my-zsh/custom/plugins/fzf-autopair/autopair.zsh
      autopair-init
      autoload zcalc
      source /usr/share/fzf/key-bindings.zsh # This might be Arch Linux specific?
      

      There are tons of different ways to install all these plugins, but I just clone their repositories into my home directory and use a program like myrepos to track and periodically pull the latest changes from git. This is the directory layout of the various plugins:

      $HOME/.oh-my-zsh
      $HOME/.oh-my-zsh/custom/plugins/fzf-autopair
      $HOME/.oh-my-zsh/custom/plugins/fzf-tab
      $HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions
      $HOME/.oh-my-zsh/custom/plugins/zsh-completions
      $HOME/.oh-my-zsh/custom/plugins/zsh-history-substring-search
      $HOME/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
      $HOME/.oh-my-zsh/custom/plugins/zsh-z
      $HOME/.oh-my-zsh/custom/themes/powerlevel10k
      

      And this is what it looks like in my $HOME/.mrconfig file:

      [.oh-my-zsh/custom/plugins/fzf-autopair]
      checkout = git clone 'https://github.com/hlissner/zsh-autopair.git' 'fzf-autopair'
      
      [.oh-my-zsh/custom/plugins/fzf-tab]
      checkout = git clone 'https://github.com/Aloxaf/fzf-tab.git' 'fzf-tab'
      
      [.oh-my-zsh/custom/plugins/zsh-autosuggestions]
      checkout = git clone 'https://github.com/zsh-users/zsh-autosuggestions.git' 'zsh-autosuggestions'
      
      [.oh-my-zsh/custom/plugins/zsh-completions]
      checkout = git clone 'https://github.com/zsh-users/zsh-completions.git' 'zsh-completions'
      
      [.oh-my-zsh/custom/plugins/zsh-history-substring-search]
      checkout = git clone 'https://github.com/zsh-users/zsh-history-substring-search.git' 'zsh-history-substring-search'
      
      [.oh-my-zsh/custom/plugins/zsh-syntax-highlighting]
      checkout = git clone 'https://github.com/zsh-users/zsh-syntax-highlighting.git' 'zsh-syntax-highlighting'
      
      [.oh-my-zsh/custom/plugins/zsh-z]
      checkout = git clone 'https://github.com/agkozak/zsh-z.git' 'zsh-z'
      
      [.oh-my-zsh/custom/themes/powerlevel10k]
      checkout = git clone 'https://github.com/romkatv/powerlevel10k.git' 'powerlevel10k'
      
      [.oh-my-zsh]
      checkout = git clone 'https://github.com/ohmyzsh/ohmyzsh.git' '.oh-my-zsh'
      

      As for Fish:

      Fish is great, I would just note that it isn't POSIX-compatible. When I tried Fish, this wasn't a big deal. It made using one-liners in the terminal trickier, because I might have to adapt them to Fish's syntax, but mostly it just meant sticking Bash code into script files and making sure they had the proper shebang.

      You can't really go wrong with Fish, it's a good shell. The only reason I don't use it is that I had already configured Zsh by the time I tried Fish, and wasn't compelled to permanently switch.

      8 votes
    3. [2]
      json
      Link Parent
      How to form various commands is something i often ask ChatGPT about.

      How to form various commands is something i often ask ChatGPT about.

      1. Minori
        Link Parent
        This works great...assuming you're not using undocumented internal CLIs that some long-forgotten dev created aeons ago. That, vim, grep, ls, cd, and less make up my CLI usage. The grep...

        This works great...assuming you're not using undocumented internal CLIs that some long-forgotten dev created aeons ago. That, vim, grep, ls, cd, and less make up my CLI usage. The grep alternatives aren't viable due to company-specific file encryption...

  3. crdpa
    Link
    Helix, Fish and nnn are the three tools I install from the start. Love the text.

    Helix, Fish and nnn are the three tools I install from the start.

    Love the text.

    4 votes
  4. [3]
    first-must-burn
    Link
    Another CLI tool recommendation: Task It has a nice yaml syntax, the ability to build tasks up from sub tasks, the ability to parameterize tasks using the Golang template tools, the ability to...

    Another CLI tool recommendation:
    Task

    It has a nice yaml syntax, the ability to build tasks up from sub tasks, the ability to parameterize tasks using the Golang template tools, the ability to import task files (namespaced) so you can break tasks down across your project structure. It has preconditions, tasks can call other tasks, etc.

    It's a standalone binary written in Go, so super easy to install.

    All of of my containerized dev projects start with task env-build, task env-run, task env-term. Then I add standalone build, test, watch, etc as needed. For the project that uses k3d for local dev (including setting up a local image repo to push to), everything is a task so it's super quick to get a new environment up and running or reset a borked one.

    For people that would use make to automate a bunch of repeatable tasks, I recommend this as a much more readable and powerful alternative.

    For JS developers, it's a little like npm run thing turned up to 11.

    Technically task does have the ability to skip tasks whose inputs haven't changed, making it a full Make replacement. However, I don't think this is its strength. I would use a language specific build system (Cmake, vite, the go tool stack, etc) and have everything invoked by task.

    2 votes
    1. [2]
      priw8
      Link Parent
      A rather unfortunate coincidence is that both the tool you mentioned and taskwarrior have the same command name - task. Though I'm sure you can work around it with some symlinks somehow. Speaking...

      A rather unfortunate coincidence is that both the tool you mentioned and taskwarrior have the same command name - task. Though I'm sure you can work around it with some symlinks somehow.

      Speaking of which, I definitely recommend taskwarrior!

      2 votes
      1. first-must-burn
        Link Parent
        Interesting. I don't think I'm at a CLI enough to make use of it, but I can see the appeal. You should always alias it to tw or something, which also saves keystrokes. For example, I have kubectl...

        Interesting. I don't think I'm at a CLI enough to make use of it, but I can see the appeal. You should always alias it to tw or something, which also saves keystrokes. For example, I have kubectl aliased to kc.

        For general life things, I need something for mobile because I'm a "write it down when I think of it so I don't forget" kind of person. For that, I use Joplin. The sync is iffy (when syncing many devices to dropbox) so I have it on my list to find something that syncs more smoothly, but I hate it less than other things I have tried.

        For work (I do contract software development, among other things) I generally keep a task list in a google doc or other shared doc as a means of communicating with my clients.

  5. pete_the_paper_boat
    Link
    nu's approach is by far my absolute favorite, putting data first is an absolute blessing. It's saved me a lot of time python scripting or looking up how to clunkily put something equivalent into bash.

    nu's approach is by far my absolute favorite, putting data first is an absolute blessing. It's saved me a lot of time python scripting or looking up how to clunkily put something equivalent into bash.

    2 votes
  6. [2]
    Happy_Shredder
    Link
    For some reason vifm is a bit unknown. It's a terminal file manager, ala Midnight (Norton) Commander. With vi keybindings (plus other features). I always feel a bit lost when I log into a system...

    For some reason vifm is a bit unknown. It's a terminal file manager, ala Midnight (Norton) Commander. With vi keybindings (plus other features). I always feel a bit lost when I log into a system without it.

    2 votes
    1. greyfire
      Link Parent
      I live on the command line and in vim, and this is my new favorite thing. Thanks!

      I live on the command line and in vim, and this is my new favorite thing. Thanks!

      1 vote
  7. trim
    Link
    I've recently started to use hurl , as a replacement for all the GUI API testing tools , which mostly seem to be going down user hostile roads these days. Just finished converting a bunch of api...

    I've recently started to use hurl , as a replacement for all the GUI API testing tools , which mostly seem to be going down user hostile roads these days.

    Just finished converting a bunch of api tests to hurl files. Works really well for my use cases.

    CLI ftw

    2 votes
  8. Reapy
    Link
    I really enjoyed the write up, thank you for sharing! I have a mixed feeling on CLI myself, I think I'm a visual person perhaps, but I also don't like to take my hands of the keyboard if i can...

    I really enjoyed the write up, thank you for sharing!

    I have a mixed feeling on CLI myself, I think I'm a visual person perhaps, but I also don't like to take my hands of the keyboard if i can help it! Using a computer to me started as CLI but just as fast we had norton comander to show me something visual and I had a much easier time navigating and moving this around to locations. For some reason, it is easier for me to see the buckets rather than comprehending raw ls output or reading my path off the shell.

    I know there are some modern shells and I took a look at nushell and that seemed exciting, but overall my experience with shell scripts and/or using linux tools and piping is just that I don't think about computing that way. Really don't get me started at how unportable bash scripts seem to be to other machines, but also how finicky it is about whitespace and other things, it's really hard to really get into a flow with it, but it is still a powerful tool. We can skip over the dark days of windows batch scripts, but also powershell didn't feel that much more fun to code in (having tried a few), though i'll give it chatgpt has gotten me to write myself more powershell scripts here and there for small time saving.

    At the end of the day my real preference is when the keyboard input is married up with visual input. Seeing how a lot of the rich text editors like sublime text give you the cmd shift p menus was something that was hard from me to move away from. I really enjoy in code editors having the mini map on the side and it is alright for me to grab my mouse and do something as well.

    I really enjoy flow launcher for navigating around, I don't like to drag and click target and would rather type to bring up, but after that am ok with mouse use. I also just really need to see things, and I like thigns as list or in lists with good visualization.

    I don't do a lot of working with networks and removing into machines, if that was my daily driver I would probably be more engaged with the command line, but even then I just never really could become a person that could flawlessly use the CLI tools to achieve quick analysis or searching. If I have to think for a bit on things I just end up shell scripting or a short python script and never felt like I mastered CLI.

    Finally I think the ultimate representation of what I think is neat is textual. I haven't had a chance to write anything in it yet (I had used the creators his rich library previously), but you can essentially write a GUI that runs over the shell and it's one of the coolest things to exist in my brain about what I like about computing. The CLI is this sort of neat wonderful thing but I really do need some pinned floating lists and stuff for information reference, I'm terrible at short term retention so I just can't really flourish in a pure CLI use of a computer.

    1 vote
  9. mxuribe
    Link
    Hi @Toric i just read the post, and it was great! Firstly, keep on writing more! :-) Secondly, i find myself more and more using CLI tools, and enjoying to do so! I think its more because i feel...

    Hi @Toric i just read the post, and it was great! Firstly, keep on writing more! :-)

    Secondly, i find myself more and more using CLI tools, and enjoying to do so! I think its more because i feel more productive. Whether its factually true or not, well, who cares. As long as i get my stuff done, then cool.

    Also, separately, i do think that this whole AI trend to use prompts is so conceptually similar to CLI usage, that its certainly driving the more recent popularity in increase of CLI tools. I guess time will tell...but i envision more non-techie users beginning to leverage more CLI tools - at least to some degree - simply from being accustomed to using AI platforms via prompts. I have a somewhat funny prediction: I predict that in the coming years (like in a handful of years, and not decades) that "using the command line" and "using AI prompts" will merge into a single "way of working". ;-)

    Anyway, again, keep on writing! Cheers!

    1 vote
  10. Eji1700
    Link
    Happy to see some talk about nushell, as it's what i've been screwing around with. My main environments are almost all windows machines, but I find powershell to be overly burdened with ugly...

    Happy to see some talk about nushell, as it's what i've been screwing around with.

    My main environments are almost all windows machines, but I find powershell to be overly burdened with ugly boilerplate, and nushell to (mostly) be cleaner.

    I do like the verboseness of powershell (making it very easy to understand what you're doing, or where to look for it, instead of just need to know what things like grep or touch do), but nushell seems to strike a really nice middle ground with MUCH better error handling.

    There's still a few edge cases in my testing that have bugged me about nushell (not that I can recall them at the moment), and I haven't bothered to really do any serious scripting in it, but I certainly don't enjoy when I can't use it.