Wikimedia Discovery/Command Line Tricks

This is a collection of useful *nix command line tricks and productivity tips that not everyone knows about that could improve your command-line fu. Note that not all versions of *nix are created equal, so some of these may work in some OSes or some shells but not in others. (OTOH, once you know it's possible, you can usually find a way to make it happen in your OS/shell.)

Commands
Each command here has a brief description, a use case or two, and an example or three if needed.

pushd, popd, pushd

 * description: controls a stack of directories.  moves you to and pushes onto a stack.   pops the stack and moves you back to your previous directory.   (with no argument) swaps the top two items on the stack.
 * use case: jumping back and forth between two directories (config in, running stuff in ), changing directories one or more times and then changing back without having to keep track of the list of directories (e.g., in a bash script)
 * see also https://en.wikipedia.org/wiki/Pushd_and_popd

` ` or $( )

 * description: convert the output of a command into command line arguments;  can be embedded—whether that is good or bad is left as an exercise for the reader.
 * example:
 * or  create a file with today's date as part of the filename using   to get today's date
 * use the output of the previous command (say, something complicated involving ) as command line arguments for
 * open all files in this directory tree that contain  but do not have   in their name.

!!, !<#>, !, !$

 * description:
 * repeats the last command, possibly in a new context;
 * repeats the command two steps back in your history.  is the same as  .   repeats command 445 from the output of.
 * will re-run your most recent  command.
 * is the last argument from the previous command
 * example:
 * repeat previous command with sudo
 * use the output of the previous command (say, something complicated involving ) as command line arguments for
 * repeat the previous command twice (do it several times and you will repeat the command 4 times, 8 times, 16 times, etc.)
 * followed by  adds the file you were just editing to git. Alternatively inside vim   to refer to current file. ex:
 * See also: https://jaysoo.ca/2009/09/16/unix-history-and-bang-commands/

bash scripting

 * description: shell scripts can be really powerful. Simple loops are super useful...
 * example:
 * copy every .cfg file into directory bk/
 * copy every .cfg file to a .cfg.bk backup in the same directory
 * Note though that parsing ls output can be error prone. What if a file has a space in it's name? Use find with null delimited strings:
 * But really find is pretty powerful all on its own and will handle oddities like files with spaces without thinking about it
 * see http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
 * see http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
 * see http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html

grep -R

 * description: recursive, searches all files in this directory and every directory below it. Not as powerful as   but easier to remember
 * example:  open all files in this directory tree that contain   but do not have   in their name.

typing the hard-to-type

 * Type a random unicode char (Mac and Windows instructions, more)
 * Commonly used characters:
 * interpret (most usefully for tab or return) as just a character. Also works in

tmux and screen

 * and  both allow you to create a terminal session that will persist after logging out.   also allows you to split screens and do all sorts of other cool stuff. To learn more—use the Google-fu, Luke.

vi(m) shortcuts
A few favorite shortcuts in vi. No discussion allowed about whether vi or emacs or some other lame editor is best.
 * = replace current word
 * = replace inside parenthesis
 * = delete current word
 * = swap current character and the next one
 * = toggle case of current character;  toggles ten characters
 * = move forward one word with a restrictive definition of word (ex: stops on each / of a path)
 * = move forward one word with a generous defitinition of word (ex: a whole path is considered a single word)
 * = remove newline at end of line, merging current and next line
 * = Move to next blank line. Useful for jumping large distances in source files.  does same backwards.

Vim prettiness (adds symbols for eol, tab and spaces at the end of the line (tralling) that shouldn't be there) (vim command line or .vimrc or equivalent). This can make it easy to recognize mixed tabs/spaces for example:

To turn back off:

Config
These are cool things you can add to your .bashrc or .bash_profile to make your command line more efficient

alias
lets you rename a command (including command line options and piping commands together).
 * quit with one keystroke
 * just two keystrokes to get a long directory listing
 * now  will list only lines in your history that include
 * log into stat1002 much more easily
 * if you type it more than twice a day, make an alias!
 * makes a case-insensitive version of
 * pipe into  to get a frequency sorted list of lines; use   as the last command to get the most frequent item first; e.g.,
 * or  alias a common typo to what you intended
 * Stop typing out this crazy long path you move into several times a day. Now you can cdc and go there.
 * a quick list of subdirectories with sizes.
 * How much space is left?

history config

 * Only keep one copy of any give command in your history. Very useful is you repeat the same command or set of commands over and over without filling up your history
 * If the histappend shell option is enabled, the lines are appended to the history file, otherwise the history file is over-written.
 * synch up history across all terminals
 * is run every time before a command line prompt is displayed
 * appends this terminal's history to the history file;  appends the history file to this terminal's history
 * See also https://www.gnu.org/software/bash/manual/bashref.html#Bash-History-Builtins
 * hold on to more history
 * # Number of lines in history. Arbitrarily large so histfilesize takes over
 * # Number of bytes in history
 * # Number of bytes in history

export LC_ALL=en_US.UTF-8
Makes lots of stuff work better with Unicode

custom bash prompt (PS1)
You can add all sorts of useful information into your bash prompt, including emoji, directories, the time, color, and more. Add some version of these commands to your  or equivalent. It can be useful to have one color/emoji/etc on one (real/virtual) machine and a different config on another, so you can always tell where you are.
 * Using emojis for local sessions:
 * Add color (green) and current time:
 * Show current  branch in your prompt:
 * See also:
 * https://www.cyberciti.biz/tips/howto-linux-unix-bash-shell-setup-prompt.html
 * https://www.cyberciti.biz/faq/bash-shell-change-the-color-of-my-shell-prompt-under-linux-or-unix/

SSH config
See https://wikitech.wikimedia.org/wiki/Managing_multiple_SSH_agents and https://office.wikimedia.org/wiki/Discovery_Analytics#SSH_Configuration

For Mac-specific SSH key config, see https://github.com/jirsbek/SSH-keys-in-macOS-Sierra-keychain

Other Specific Tools
These are some specific tools that people have configured for themselves. They may or may not be useful, but may also provide inspiration.

up
A bash function (goes in  or equivalent) to navigate around deep directory trees: Usage:   goes up three directories

Auto-magic tmux into place on first opened console from .bashrc (with irc):
Turns on  and opens an irc session using irssi on login. is generally awesome and has many cool features.

Navigation
These are some useful command-line navigation shortcuts.

up-arrow & down-arrow
Move through previous command line commands; edit or just re-run them

CTRL-r
Search back through your history for a command matching what you type. will take you to your last command with  in it. again will jump back to the matching command before that!

emacs-style navigation & cut/paste

 * CRTL-e: go to end of line
 * CRTL-a: go to begin
 * CRTL-k: cut to the end
 * CTRL-u: cut to the begin
 * CRTL-w: cut the previous word
 * CRTL-y: paste
 * ALT-f: forward one word
 * ALT-b: backwards one word