from Hacker News

Mastering Bash and Terminal

by blockloop on 1/14/17, 8:21 PM with 180 comments

  • by Normal_gaussian on 1/14/17, 9:09 PM

    Rather than temporarily suspend vim to use the terminal you can get vim to suspend and resume itself with the exclamation mark command. This has the benefit of not wreaking havoc on your vim session and allowing you to read data into vim by prefixing with r.

    For example

        :!ls
        
    will execute ls and show you the result (press enter to return)

        :r!ls
    
    will read the result of ls in for you

    More usefully

        :r!sed -n5,10p that/other/file
    
    will read lines 5-10 from that other file.

    However you will most often want to

        :!make
        :!up build
        :!git status
        :!git commit -am "Fixed #23"
  • by greenspot on 1/15/17, 12:25 PM

    Great post & thread, a tl;dr:

      Ctrl-r      search history
                  - then Ctrl-r again to show next match
                  - then Tab to show all options
      Ctrl-p      previous command or arrow up
      Ctrl-n      next command or arrow down
      export HISTCONTROL=ignoreboth:erasedups
                  Add to .bashrc to avoid duplicate entries
    
      Ctrl-a      to beginning of line
      Ctrl-e      to end of line
      Alt-b       one word back
      Alt-f       one word forward
      Ctrl-k      delete to end of line
      Ctrl-u      delete to beginning of line
      Alt-d       delete to end of word
      Ctrl-w      delete to beginning of word
      Alt-Backspc same
    
      cd -        change to last dir
      pushd <dir> mark current dir and go to <dir>
      popd        go to marked dir 
      z           fuzzy cd, install from https://github.com/rupa/z
      j           fuzzy cd and more, install via autojump
    
      Ctrl-z      to background & suspend
      bg          recent background app continue running
      fg          bring recent background app to front
      disown -h   remove recent background app from current tty
      fg %n       bring nth app to front, e.g.: fg %2 for second
    
      less        better than cat, doesn't flood screen, same keys
      find        find files, e.g. find / -name <filename>
    
      ag          install via the_silver_searcher, faster grep
    
      tree        shows dir like a GUI app, install
      !!          last command, e.g. sudo !!
      fish        bash alternative with more sensible defaults
    
      man bash    read more about bash
  • by oblio on 1/14/17, 9:33 PM

    The article is nice but a small part of it rubs me the wrong way:

    > I know there are some cool newcomers out there like zsh and fish, but after trying others out I always found that some of my utilities were missing or ill-replaced.

    First of all bash was first released in 1989 and zsh arrived just 1 year later so zsh is in no way a newcomer.

    Secondly zsh is almost strictly a bash superset so I don't know what he was missing (or what he found "ill-replaced").

  • by teddyh on 1/14/17, 9:40 PM

    Regarding macOS and bash, it is slightly remiss of the article to not at least mention that the version of bash in macOS is

    1. Ancient.

    2. Will most likely never be updated by Apple

    (Most GNU- and Linux-based systems, and also Windows, on the other hand, continue to use the latest versions.)

  • by whack on 1/14/17, 10:11 PM

    Personally, I found the following to be extremely easy and powerful. A no-brainer that should be a bash default really.

      if [ -t 1 ]
      then
        #   search for commands that start off with the same characters already typed
        bind '"\e[A":history-search-backward'
        bind '"\e[B":history-search-forward'
      fi
    
    One of my friends also recommended version-controlling your config files and storing them on gitlab, which I'm only sad I didn't do sooner. It's been such a help in keeping my aliases and configs in sync, as I make changes across numerous different machines.
  • by h2hn on 1/15/17, 12:13 AM

    I actually resolved most of that common issues with just bash: :)

    Substring history search, so you can use just a substring to look for a argument,command. Binded to ctr+r/s by default. ;)

    https://github.com/liloman/asyncBash#use

    Changing directories: Last n directories, transparent popd/pushd.

    https://github.com/liloman/dirStack

    Movements: vim-surround for your cli, so you can do ysiw" o whatever... ;)

    https://github.com/liloman/bash-surround

    Control-n right: So just type the start and control+n to search for the arguments/commands starting with whatever. And the classical up/down to look up for a complete history line:

    https://github.com/liloman/dotfiles/blob/master/bash/.inputr...

    https://github.com/liloman/dotfiles/blob/master/bash/.inputr...

    There're a ton of hidden functionality and customization behind the classical bash instalation. :)

  • by wyclif on 1/15/17, 1:22 AM

    I also assume you're using bash. I know there are some cool newcomers out there like zsh and fish

    While there is much useful in this post, I always find comments like this one odd. bash was released back in 1989, zsh was released one year later, in 1990. One year difference in age almost thirty years ago means that you can't really call zsh a newcomer. Maybe he's talking about adoption, though.

  • by alphast0rm on 1/14/17, 9:20 PM

    For changing directories, you can also use something like z (https://github.com/rupa/z) to jump around:

           Tracks your most used directories, based on 'frecency'.
    
           After  a  short  learning  phase, z will take you to the most 'frecent'
           directory that matches ALL of the regexes given on the command line, in
           order.
    
           For example, z foo bar would match /foo/bar but not /bar/foo.
  • by TheAceOfHearts on 1/15/17, 7:57 AM

    I've tried bash, zsh, and fish. After trying all three, I'm staying with fish. bash and zsh don't have sensible defaults, and configuring them is tedious. fish works great out of the box, and it's really fast. When I picked up zsh I used oh-my-zsh and later prezto, but it was slow and figuring out what everything all the framework did was complicated.

    With fish I have a setup.fish script that defines all my universal exports, for when I setup a new computer. This is for private tokens, like HOMEBREW_GITHUB_API_TOKEN. For aliases and utilities, I wrote a fisherman [0] plugin. It has a functions folder and a fishfile for the few other plugins I use.

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

  • by why-el on 1/15/17, 2:44 AM

    In the spirit of sharing: one of my favorite lines in my bashrc is the alias of `rm` to `rm -i`. This prompts for a confirmation. You might not need it but I deleted some important, not-yet-checked-in-git files in the past by accident.

    If you want to delete everything and don't want to keep typing yes just do `yes | rm bla`.

  • by lxe on 1/15/17, 3:57 AM

    The one tool that saved me quite possibly a few months of typing paths over my lifetime is autojump: https://github.com/wting/autojump. I can't imaging a terminal workflow without it.
  • by xolb on 1/14/17, 11:31 PM

    One that I learned from Mr. Robot: put a space before the command to avoid being registered in the history.
  • by alkonaut on 1/15/17, 9:50 AM

    > "tool that every developer uses regardless of language, platform, or framework it's the terminal"

    I'm not sure I agree with that. If you work in a decent IDE and your vcs is not git then you can do pretty well without a terminal. Especially on Windows.

  • by llasram on 1/15/17, 12:12 AM

    Worth it just for finding out about `stty -ixon`. I never would have guessed from the `stty` man page description that this option would give me back C-s and C-q to bind to something actually useful.
  • by pmoriarty on 1/15/17, 12:19 AM

    bash (and shells in general) are so hacky (in a bad way) that I wouldn't want to waste my time mastering them. Whenever a shell script grows beyond 10 or 20 lines, I try to rewrite it in a "real" programming language. Fancy shell tricks are a code smell to me, and clarity and simplicity are of far greater importance.

    For me, as far as shells go it's usually enough to know the basics and be able to look stuff up when debugging other people's shell scripts.

  • by johnchristopher on 1/15/17, 12:11 PM

    I love `set -o vi`. It gives you vim motion in the terminal.
  • by gigatexal on 1/14/17, 11:38 PM

    Instead of ctrl-z and bg why not just do # <cmd> & to push it to the background.
  • by gogolb on 1/14/17, 10:35 PM

    On macOS, instead of

        ip addr show en0 | grep -inet\ | awk '{ print $3 }' | awk -F/ '{print $1}' | pbcopy
    
    you can use:

        ipconfig getifaddr en0
    
    If you wanna stick with ip addr, a more compact command is:

        ip addr show en0 | awk '/inet/{split($2,a,"/"); print a[1]}'
  • by Scea91 on 1/15/17, 4:53 PM

    One thing I am struggling with is that when I use several terminal windows then the history is not recorded immediately and history from one window is not available in other windows. Some time ago I was looking up how to solve this but didn't find a solution that would work for me.
  • by hiq on 1/15/17, 12:14 AM

    About bindings, it would have been better to redirect to:

    LESS=+/"DEFAULT KEY BINDINGS" man readline

    assuming it exists on mac.

    About suspend, what's the benefit of suspending vim using C-z? Shouldn't you use a terminal multiplexer instead, or even terminal tabs if you don't want to learn how to use tmux or screen (which I find weird if you already spent time to learn how to use vim but alright)?

    I only ever suspend a program when I want it to stop, for instance because it slows other programs and I realize I would rather resume it when I'm not in front of my computer. Even in that case, I often just renice the program instead. Stopping a program just because you want to run some bash commands looks like an anti-pattern to me, but maybe there are better motives I'm not aware of.

  • by danielrm26 on 1/15/17, 2:50 AM

    Rather than trying to remember all those commands for moving around in your command, I recommend turning on vim mode for the command line, and remapping ESC to "jk".

    bindkey -v bindkey -M viins 'jk' vi-cmd-mode

    Then you can edit your command line the same way you would edit a line in vim.

  • by blunte on 1/15/17, 10:55 AM

    Those Emacs commands you mention for moving around on the line also work in a lot of other text fields, in a lot of other programs.

    Notably they don't work in MS Office, but they work in web browsers and practically every other app I have on my Mac.

  • by santaclaus on 1/14/17, 10:34 PM

    I'm curious about the popularity of Bash vis a vis, say, Csh. Is Bash more popular due to superior features, or is simply because it is the default on quite a few *nix distros (and macOS)?
  • by coldtea on 1/15/17, 2:31 PM

    >If there is one tool that every developer uses regardless of language, platform, or framework it's the terminal.

    Sounds like the author never heard of Windows development.

  • by Graziano_M on 1/20/17, 8:52 PM

    > Now that we know we don't need the up and down arrow keys, what about the left and right? Unfortunately, these keys are still needed for single character movements...

    What? No. Use Ctrl-f and Ctrl-b. I use this probably more than any other readline shortcut.

    Ctrl-h for backspace, Ctrl-d for delete. Half my keyboards don't even have arrow keys and I don't miss them.

  • by teddyh on 1/14/17, 9:29 PM

    > 8. alt-w - delete the word behind of the cursor

    He means “ctrl-w”. But since that only works in bash, not in Emacs or other tools with Emacs key bindings, it makes more sense to use (in his terminology) “alt-backspace”. This does the same thing, and works both in the shell and in Emacs-like environments.

  • by nurb on 1/15/17, 9:29 AM

    Another trick is to use "!!" which is the last command launched, especially useful if you forgot a "sudo" in front of your command, just write

      sudo !!
    
    In the same way, "!*" is all the arguments of your previous command, and "!$" only the last one.
  • by RJIb8RBYxzAMX9u on 1/15/17, 6:36 AM

    Regarding history, another simple trick is to increase $HISTSIZE and $HISTFILESIZE, for the defaults are woefully tiny for 2017. I set mine to a million. You could have 100 terminals open and they would still consume less RAM than <insert "native" Electron app(s) of your choice>.
  • by wodenokoto on 1/14/17, 10:00 PM

    Personally I found "Learn Enough Command Line to Be Dangerous" to be really helpful to get started with actually using the command line at all.

    https://www.learnenough.com/command-line-tutorial

  • by ivanhoe on 1/15/17, 4:06 PM

    It's missing my favourite: CTRL + _ for Undo.

    Also there's a big difference between Alt + Backspc and Ctrl + w. The first will delete a word consisting of only alphanumerics, while Ctrl + w also deletes the word, but word can be made of any characters other than space.

  • by mr_donk on 1/15/17, 6:45 AM

    > Now that we know we don't need the up and down arrow keys, what about the left and right? Unfortunately, these keys are still needed for single character movements

    Don't ctrl-f and ctrl-b work?

  • by rofrol on 1/18/17, 6:25 PM

  • by ndesaulniers on 1/15/17, 5:26 AM

    When going past something with ctrl+r, use backspace rather than ctrl+s. less has movements similar to vim. In less, hit v to open the file in your editor.
  • by annetee on 1/15/17, 10:15 PM

    Also:

    Alt-l converts next word to lowercase

    Alt-u converts next work to uppercase

  • by thiagof on 1/15/17, 8:05 PM

    A very usefull command is Alt-m. This command repeat the last digited string in the current line. It only works in ZSH.
  • by cel1ne on 1/15/17, 11:37 AM

    Tipp for OSX-Terminal:

    Option + Cursor-Left/Cursor-Right to jump words

  • by rerx on 1/23/17, 10:02 AM

    I never knew of `cd -` before -- very useful!
  • by philonoist on 1/15/17, 6:03 AM

    Kindly help me out on how to learn this tool in Windows10 without using VM?
  • by greenspot on 1/15/17, 9:56 AM

    tl:dr

      ctrl-r     search in history, ctrl-r again to skip-
      ctrl-p     previous command (instead of arrow up)
      ctri-n
  • by lisivka on 1/14/17, 9:37 PM

    I recommend to install mc (Midnigth Commander) and bash-completion (if bash is your shell of choice) as first terminal tools.

    mc allows to explore system efficiently while not standing in my way, because I can always press ctrl-O and get my shell back.

    bash-completion saves time on typing of commands.

    Other tools I install often are htop (better ps) and strace.

  • by krzyk on 1/14/17, 10:36 PM

    It would be good to mention that this article is MacOS centric.
  • by SFJulie on 1/14/17, 11:59 PM

    Seriously you can get on fi(r)st page of HN with 5% of man bash?