8 ms·
Bash Shortcuts For Maximum Productivity
- gaving 15y agoI'm a zsh user, but here's a couple of things I find pretty invaluable:- bindkey '^Q' push-line The 'push-line' widget allows you to quickly type another command and will restore the previous one once you've entered it. # re-run the previous command with sudo rerun-with-sudo () { LBUFFER="sudo !!" zle accept-line } zle -N rerun-with-sudo bindkey '^Xx' rerun-with-sudo Re-run the previous command prefixed with sudo by typing ^X then x. And:- # build git clone command from clipboard git-clone-clipboard() { REPO_URL="$($CLIPBOARD)" REPO_BASE_NAME=${$(basename $REPO_URL)%.git} LBUFFER="nocorrect git clone $REPO_URL $REPO_BASE_NAME" } zle -N git-clone-clipboard bindkey "^Xg" git-clone-clipboard ^Xg prefixes a git url with "git clone" and fills out the command line. Couple similar things for wget, youtube-dl here: https://github.com/gaving/dotfiles/blob/master/.zsh/config https://github.com/gaving/dotfiles/blob/master/.zsh/config
- pmr_ 15y agoIf I have a URL in my clipboard and want to prefix it I use: git clone `xclip -o` Much simpler and no customization needed.
- gaving 15y agouh, why wouldn't you just actually paste the url into your terminal at that point instead of typing `xclip -o`? and yeah, typing the actual command into the terminal is always going to be 'simpler'
- tednaleid 15y agoI'm also a big zsh user, one of the biggest timesavers for me was to get autocompletion of the arguments from the last command working. I use meta-. for the last argument, but !:# syntax is awkward and I don't often remember exactly what number parameter something was. Took a bit of screwing around, but I eventually figured it out and the details are on the unix/linux stack exchange site: http://unix.stackexchange.com/questions/5229/add-arguments-from-previous-command-to-zsh-completion http://unix.stackexchange.com/questions/5229/add-arguments-f...
- pooriaazimi 15y agoA note to Mac users: Instead of Alt, you must press escape key. For example, Esc+b moves the cursor backward one word in bash, but you'll probably want to use option instead, so check 'Use option as meta key' in Terminal's settings (under keyboard tab). But if it's not very handy, you can set 'option+left arrow' to move cursor one word backward. To do that, open Terminal's settings, go to keyboard and add a shortcut for left arrow (with 'option' as modifier), and leave the action to 'send string to shell'. Then click on the textbox below that and press esc (which should print '\033') and then 'b', or simply type '\033b' in the textbox. Just this simple shortcut makes Mac's Terminal 1000 times better.
- ghshephard 15y agoThanks very, very much. I'm embarrassed to admit I probably spend 3-5 hours a day on a command line, and have just gotten used to set -o vi when I need to bounce around long lines a lot. esc+f/esc+b were always awkward. It should have occurred to me to just map the keys on Terminal.app! In the interesting news department - Lion already has option left cursor/right cursor already mapped to move a word forward and back - not sure if it was there in snow leopard.
- spatten 15y agoTotally agreed. I also have 'option+right arrow' mapped to move cursor one word forward (use the same instructions as above, substituting 'f' for 'b').
- raju 15y agoI am iTerm user so for those folks here is the setup you need to make "option" key the 'meta' key in iTerm http://stackoverflow.com/questions/196357/making-iterm-to-translate-meta-key-in-the-same-way-as-in-other-oses http://stackoverflow.com/questions/196357/making-iterm-to-tr... I still don't like it since I am so used to hitting the Apple key in emacs, but it beats having to use Esc+<letter>
- bsergean 15y agoI noticed a lot of Vim post recently, you can use the vim binding inside your shell too as discussed in that post, downside is that you'll have to type on Esc a lot.
- dhugiaskmak 15y agoI've been using this[1] page as a cheatsheet for readline commands. [1] http://jan.tomka.name/sites/default/files/readline-commands.html http://jan.tomka.name/sites/default/files/readline-commands....
- andrewflnr 15y agoOne of my favorite bash shortcuts is binding the up arrow to history-search-backward. This is the first page I found that concisely explains how; the variant in the second comment is the one actually in my .bashrc: http://hints.macworld.com/article.php?story=20031026174236860 http://hints.macworld.com/article.php?story=2003102617423686... So if you've typed `verylongcommand` some indeterminate time in the past, you can probably just type "ver<up>", and you'll have it. Very convenient.
- irahul 15y agoA quick look at the article shows it's binding history search. It's already bind to ctrl-r - you can do a ctrl-r, type a few letters of the long commands, and keep doing a ctrl-r till you find the right match. Apart from additional bind your setup requires, arrow keys are near impossible to touch type. Even if you can touch type them, that means taking your hands off the home row, and positioning them again.
- bostonvaulter2 15y agoI think with the parent's setup you can do ver<C-p> to get the same effect.
- graywh 15y agoI use ctrl-P/N for history-beginning-search-{backward,forward} in Zsh. Type the start of a previous command and cycle through the matches.
- tedkalaw 15y agoI'm not an Emacs user, but aren't a lot of the text-editing shortcuts straight from Emacs?
- aerique 15y agoYup, but you can also put Bash in a vi mode. Some else will to chip in with the exact incantation, since I'm on my phone now.
- pyre 15y agoset -o emacs or set -o vi
- irahul 15y agoThe text editing shortcuts are straight from readline http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html emacs bindings, which bash and many other programs use. readline supports both vi and emacs bindings. I am a dyed in the wool vim enthusiast, but when it comes to command line bindings, emacs' bindings are more convenient.
- unfletch 15y agoThe things he calls "bang commands" are actually "event designators" (!!, !blah), "word designators" ($) and "word modifiers" (:p). There are links to docs for each at the bottom of this page: http://www.gnu.org/s/bash/manual/html_node/History-Interaction.html#History-Interaction http://www.gnu.org/s/bash/manual/html_node/History-Interacti... I use them all the time, and anyone watching over my shoulder always asks what that was. Learn !!, !$, and a few modifiers. You'll be glad you did. Personally, I use !$ constantly (and variations like !-2$, which gets you the last arg from 2 commands ago). The "h" modifier is handy, too. It's like dirname for the word. Consider this example, where you copy a file to some deep path, and then cd to that dir to continue working with the copy: $ cp foo.txt /some/really/long/destination/bar.txt $ cd !$:h $ # (do more with ./bar.txt) The substitution (:s) and global substitution (:gs) modifiers are also useful: $ echo some args some args $ !!:s/some/more more args (Also, note that his explanation of !* is actually incorrect. He says it leaves off the last arg, but actually leaves out $0 (the command name). !* is all of the previous command's arguments.) Finally, one really useful thing he doesn't mention at all is brace expansion. For example, these are equivalent: $ cp foo.conf foo.conf.bak $ cp foo.conf{,.bak} http://www.gnu.org/s/bash/manual/html_node/Brace-Expansion.html http://www.gnu.org/s/bash/manual/html_node/Brace-Expansion.h...
- drothlis 15y agoI used to use !$ all the time, but these days I tend to go for M-. which inserts the last argument interactively, and cycles through the last argument of all previous commands (but you don't get modifiers like !$:h). http://www.gnu.org/s/bash/manual/html_node/Commands-For-History.html#Commands-For-History http://www.gnu.org/s/bash/manual/html_node/Commands-For-Hist... M-C-y (yank-nth-arg) works similarly for the first argument of the previous command, but without cycling through all previous commands. After the more complex modifiers like !$:p, :e, :s/old/new/, etc, before hitting Return I often use M-C-e (shell-expand-line) just to check I got it right. http://www.gnu.org/s/bash/manual/html_node/Miscellaneous-Commands.html#Miscellaneous-Commands http://www.gnu.org/s/bash/manual/html_node/Miscellaneous-Com...
- pyre 15y agoA neat thing about csh/tcsh is that you can use history expansion with aliases. There are some legacy aliases at work that allow SQL queries from the command line using this: $ alias select='sqlcommand -s "select !*"' would translate: $ select * from tablename to: $ sqlcommand -s "select * from tablename" (Note: I may be getting the specifics messed up as it's been a couple of years since I looked at the implementation, but the general idea is there.)
- arckiearc 15y agoGreat tips. !! is a nice timesaver when you've forgotten to prepend sudo to a command: $ /etc/init.d/rabbitmq-server restart Failed, need root access $ sudo !! Success cd - is also quite cool, it takes you to the previous working directory. $ pwd /some/really/long/path/goes/here $ cd /var/log/app Work in this directory for a while, then go to previous dir $ cd - $ pwd /some/really/long/path/goes/here
- joshu 15y agoDon't forget pushd and popd.
- graywh 15y agoFor Zsh, setopt autopushd
- gommm 15y agoI have the following in my zshrc for sudo. It adds sudo at the beginning of the current line or writes sudo !! if the current line is empty. I've aliased it to alt+s run-with-sudo() { if [[ -z $LBUFFER ]]; then LBUFFER="sudo !!"; else LBUFFER="sudo $LBUFFER"; fi }; zle -N run-with-sudo; bindkey '\es' run-with-sudo
- dongsheng 15y agoI use `..` to go upper directory, `...` to go up two levels, I added this to bashrc: str='..' level='./../' for i in `seq 1 10`; do eval "alias '$str=cd $level'" level=$level'../' str=$str'.' done Note, seq is not available in Mac, should use jot instead.
- imurray 15y agoThere's no need for seq or jot. In bash you can replace `seq 1 10` with {1..10}. Or {01..10} if you want zero padding when using $i to label files. I use an function called "up" that takes an optional integer argument to go up a certain number of levels. It won't necessarily be faster, but somehow I prefer it to typing lots of dots in a row: function up () { if test $# = 1 ; then s=$( printf "%$1s" ); s=${s// /..\/}; cd $s ; else cd .. ; fi; }
- dongsheng 15y agoThanks for pointing out that
- kleiba 15y agoIt's well known that !! is a sweet little helper in case where you forgot to sudo a command. However, I find that for those cases I usually use `Up-arrow CTRL-A` to get the previous command and then go to the beginning of the line where I can type `sudo`. Is there any reason to prefer the !! variant?
- yanowitz 15y agoI do too. I think it's faster than a cycle of :p, verify it's what you want and then reexec. It's also mentally less taxing (albeit a tiny amount). But summed over a day of shell work, I think it makes a difference.
- ajross 15y agoIf you're on a non-interactive terminal. Some of us didn't throw out our teletypes. Also: when rooting boxes often one lacks space in the exploit payload to set up the tty line discipline.
- secoif 15y agocommandline and vim have easily got the most powerful, yet the most rage-inducing key mappings – ever. The worst, and most easily rectifiable aspect is the way command pairs (eg move back/forward a word) require two totally separate commands (esc + b/esc + f) instead of having one command + a generic 'reverse' meta key. In the future I hope someone has the balls to do away with this legacy tripe and popularise some more Donald-Normanesque keyboard shortcuts.
- spacemanaki 15y agoI'm not sure if you're just trolling, but I don't understand your complaints at all. What would your "Donald-Normanesque keyboard shortcuts" even look like? In Windows the arrow keys act pretty similar, don't they? left-arrow, right-arrow for moving by character, Ctrl-left-arrow, Ctrl-right-arrow for moving by word. Windows is about as Donald-Normanesque as you can get... The bash shortcuts are from readline, which (in this case, but by default?) are the same as Emacs. C-f,C-b for moving by character, M-f,M-b for moving by word. C-n,C-p for next and previous line. I think there's a vi switch for readline which would allow you to have vi style shortcuts in bash. This is nice, because it means you have one set of keyboard shortcuts in your editor and shell. Emacs users in OS X get this in any text box (at least any that supports the same defaults as the system, I'm spitting at you MS Outlook/Entourage). I'm sure you could set something up in other windows systems, like GNOME or KDE. Sure the keyboard shortcuts might be cryptic, but any keyboard shortcuts will be. Don't slag something just because you don't know the history and background behind the choices.
- dramaticus3 15y agothe best bash shortcut you could do # ln -s /usr/local/plan9/bin/rc /bin/bash
- pkrumins 15y agoI am a huge fan of maximizing productivity in the shell. I wrote these three articles a while ago: Bash emacs-like keyboard shortcuts: http://www.catonmat.net/blog/bash-emacs-editing-mode-cheat-sheet/ http://www.catonmat.net/blog/bash-emacs-editing-mode-cheat-s... Bash vi-like keyboard shortcuts: http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-sheet/ http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-shee... Definitive bash guide to command line history: http://www.catonmat.net/blog/the-definitive-guide-to-bash-command-line-history/ http://www.catonmat.net/blog/the-definitive-guide-to-bash-co... And they all come with cheat sheets. See downloads box at the bottom of each post for download links.
- dave1010uk 15y agoGreat articles. I'm just starting to get into the hang of vi. I'm giving vi-mode in bash a go (with "set -o vi") but there doesn't seem to be any indication of when I'm in command/insert mode. Is there any way to see this?
- pkrumins 15y agoI don't know of a way to do it.
- mun2mun 15y agoThere is a workaround in zsh http://superuser.com/questions/151803/how-do-i-customize-zshs-vim-mode http://superuser.com/questions/151803/how-do-i-customize-zsh...
- graywh 15y agoThe vi-mode is actually provided by readline, so bash has no knowledge of it. So, no.
- montecarl 15y agoSometimes I find myself typing out a long command and then deciding that I don't want to run it quite yet. Normally I just hit C-c run some other command first and then copy paste the long command. Surely there is someway to put the long command in history?
- gnubardt 15y agoComment it out (put a # at the front), unless your shell is set to ignore commented lines.
- montecarl 15y agoThis works great! There is even a shortcut: M-#
- lukeschlather 15y agoYou said copy-paste - are you using the OS copy-paste or readline's kill ring? C-a C-k is pretty fast, and then can be retrieved with C-y.
- montecarl 15y agoThis is another great solution. As a vim user I haven't much looked into the emacs keybindings in readline. I'll have to read up. Also the terminology was a little confusing. I didn't realize that killing a line was the same as "cutting".
- lukeschlather 15y agoYeah, and of course this does mean you have to be a little careful with M-backspace (backward-kill-word in Emacs), since it will change your kill ring. But on other hand M-backspace can be useful too if you want to get just part of a line, you can move the cursor to where you want, then M-backspace through words to grab it - if you do M-backspace repeatedly the entire string is pulled into the kill ring until you stop pressing M-BS.
- veyron 15y agoCheatsheet for emacs mode (which is what the article presumes): http://www.catonmat.net/download/readline-emacs-editing-mode-cheat-sheet.pdf http://www.catonmat.net/download/readline-emacs-editing-mode...
- Azrathud 15y agoMost of the commands there can be replaced with vi keybindings. That is, set -o vi You can type that directly into your terminal for use just in one session or in your .bashrc Type <C-]> or <Esc> just like in vim to escape into "command" mode. Most command mode commands work. E.g. '^' goes to the beginning of the line '$' goes to the end. 'i' sets bash back into insert mode.
- Ideka 15y agoTry Alt-* ls /etc/p<Alt-*>
- super_mario 15y agoThese assume you use default emacs mode. If you are vi/vim user then set -o vi will allow you to get immediately productive in bash, using vi motion commands to edit the command line.