
Ask HN: Best things in your bash_profile/aliases? - yesenadam
What are the best, most useful aliases or functions etc for bash that you&#x27;ve collected or written? Or bash scripts. Please give explanation&#x2F;usage if necessary. Ones you actually use often. Thanks!
======
Grimm665
My favorite new one that I have been using a lot:

    
    
      function cheat() {
          curl cht.sh/$1
      }
    

It queries the cht.sh cheatsheet of various Unix commands. 'cheat tar' prints:

    
    
      # To extract an uncompressed archive:
      tar -xvf /path/to/foo.tar
      
      # To create an uncompressed archive:
      tar -cvf /path/to/foo.tar /path/to/foo/
      
      # To extract a .gz archive:
      tar -xzvf /path/to/foo.tgz
      
      # To create a .gz archive:
      tar -czvf /path/to/foo.tgz /path/to/foo/
      
      # To list the content of an .gz archive:
      tar -ztvf /path/to/foo.tgz
      
      # To extract a .bz2 archive:
      tar -xjvf /path/to/foo.tgz
      
      # To create a .bz2 archive:
      tar -cjvf /path/to/foo.tgz /path/to/foo/
      
      # To extract a .tar in specified Directory:
      tar -xvf /path/to/foo.tar -C /path/to/destination/
      
      # To list the content of an .bz2 archive:
      tar -jtvf /path/to/foo.tgz
      
      # To create a .gz archive and exclude all jpg,gif,... from the tgz
      tar czvf /path/to/foo.tgz --exclude=\*.{jpg,gif,png,wmv,flv,tar.gz,zip} /path/to/foo/
      
      # To use parallel (multi-threaded) implementation of compression algorithms:
      tar -z ... -> tar -Ipigz ...
      tar -j ... -> tar -Ipbzip2 ...
      tar -J ... -> tar -Ipixz ...
    

You do have to be online, but there are ways of downloading the directory of
cheat sheets to use offline as well.

~~~
joshstrange
This is awesome, I ALWAYS have to google for how to untar an archive (I don't
do it often enough to commit to memory) thank you!

~~~
borplk
tar czvf

"create ze vucking file"

tar xzvf

"extract ze vucking files"

------
corroded
Something funny:

    
    
      alias crontab='fuck you, <insert name of colleague here>'
    

Background:

Everyone knows that in a [in]sane workplace, you ALWAYS have to lock your
machine. So this particular new hire forgot to lock her machine and one of the
seniors (senior prankster, I would say) jumped into her terminal and set a
crontab to run EVERY MINUTE.

So she comes back (we pair program so they were actually pairing that day) and
goes on with programming for a few seconds. Then she tells us to be quiet.
We're all like "WTF?" She asks, "Do you hear some robotic voice saying
something?"

At this point we're all trying to listen but to no avail. She thinks it's her
machine (which was connected to a 27" monitor) and proceeds to max the volume.
A few seconds later, the whole office hears a thundering robotic voice say
"ASSHOLE".

Everyone laughs. From that point onwards, we all had shortcuts to lock our
screens, and as an added "security" feature, we aliased our crontab to
actually say "fuck you" to our senior prankster.

~~~
ikornaselur
Most of my colleagues used zsh and oh-my-zsh, and as far as I can remember,
oh-my-zsh has a mechanism to check for updates every 14 days.

I would then set their .zshrc or whatever to end with

    
    
        echo "sleep 0.1" >> ~/.zshrc
    

so that every time they opened as hell, it would take 100ms longer to run. It
would usually take them up to 1-2 second of startup time to figure out what
was wrong.

Now my favourite part was that I edited the oh-my-zsh update script to
actually echo the original echo line into their ~/.zshrc file, so that even if
they figured out what was happening and were very vigilant with locking their
laptop, it would happen again within the next 14 days. Loved that.

------
callahad
This is tiny, but I've gotten a surprising amount of mileage out of aliasing
'fx' to

    
    
      firefox --new-instance --profile $(mktemp -d)
    

which pops open a new instance of Firefox with a completely clean, temporary
profile.

Super useful for testing sites or add-ons without influencing (or being
influenced by) by my normal browsing profile.

~~~
kalev
What would the Google Chrome equivalent look like?

~~~
scrollaway
chromium --user-data-dir $(mktemp -d)

~~~
noir_lord
Aye, learnt this when I wanted selenium profiles with some Dev plugins
available but not my main profile.

------
AJRF
Can I add something from .vimrc?

If you put the commands:

    
    
      set undofile
      set undodir=~/.vim/undodir
    

You get infinite undo in your files.

Now when you go into a file, delete or add some text and close your terminal
down, the next time you enter vim you can (re|un)do previous operations.

Has saved my ass more times than I care to mention over my career!

~~~
midgetjones
I can't believe I didn't know about this! Thanks so much :)

~~~
AJRF
I don't want to sound hyperbolic but its kind of a game changer for text
editing.

I understand why developers don't have it on by default in other text editors
(space) but seeing as I don't fill my HDD with movies or games or any other
large media like that, i've got all the space in the world.

~~~
midgetjones
I actually wrote 'game changer' in my original comment, and got rid of it for
the same reason! Now that I've added it to my vimrc, I'm now upping it to
'life-changing'

------
pixelmonkey
For Python programmers, I have a bash/zsh function called `pycd` that takes
any Python package/module name as an argument, and changes your current
working directory to be the library or site-packages location of that library,
according to the current python interpreter in your $PATH. Here it is:

    
    
        pycd () {
            pushd `python -c "import os.path, $1; print(os.path.dirname($1.__file__))"`;
        }
    

Example usage, with abbreviated $PWD shown after "»" and shell commands
entered after "$" in this example session:

    
    
        » (~/repos/web)
        $ pycd flask
        
        » (~/./v/3/e/w/l/p/s/flask)
        $ pwd
        ~/.pyenv/versions/web+site/lib/python3.6/site-packages/flask
        
        » (~/./v/3/e/w/l/p/s/flask)
        $ head app.py                                            
        # -*- coding: utf-8 -*-
        """
            flask.app
            ~~~~~~~~~
        
            This module implements the central WSGI application object.
        
            :copyright: © 2010 by the Pallets team.
            :license: BSD, see LICENSE for more details.
        """
        
        » (~/./v/3/e/w/l/p/s/flask)
        $ popd      
        ~/repos/web ~
                                        
        » (~/repos/web)
        $
    

So, usually lets you explore the source code, at the command-line, for any
Python libraries you have installed.

------
dawnerd
Not strictly an alias, but autojump has been a huge productivity booster for
me. Installing it sets up an alias of `j` which guesses the best directory to
cd to based on your cd history.

So instead of having to type `cd ~/Projects/someproject` you could just type
`j some` and it'll end up there.

[https://github.com/wting/autojump](https://github.com/wting/autojump)

~~~
jciochon
Shoutout as well to the various `warp` implementations[1,2,3]. Instead of
guessing, you set "warp points" so for your example you can do something like:

>cd ~/Projects/someproject

>wd add . some

From then on you can use `wd some` to warp to that dir.

[1]: [https://github.com/kigster/warp-dir](https://github.com/kigster/warp-
dir)

[2]: [https://github.com/mfaerevaag/wd](https://github.com/mfaerevaag/wd)

[3]: [https://github.com/troyxmccall/wd](https://github.com/troyxmccall/wd)

~~~
dawnerd
Oh that's slick! That will be helpful for a few of my similarly named projects
that autojump gets wrong sometimes.

------
zantana
I lifted most of this from the guy mentioned in the hn post in the comments
below. I don't know what shell/platform he used, but it didn't work from
twitter so I tweaked it to work on the linux boxes I typically see.

It creates a different history file from each shell session. Most of my shell
history goes back about 3 years now. The downside is you can't up arrow or
crtl R except for your current history, but you can use the histgrep function
to search everything.

I keep meaning to make another processed file which would uniq the history
without the datestamp and maybe hook into fzf, but this has been good enough
for now.

    
    
      # tricks from https://news.ycombinator.com/item?id=10162189
    
      if [ ! -d ~/.history/$(date -u +%Y/%m/) ]; then
            mkdir -p ~/.history/$(date -u +%Y/%m/)
      fi
      #cat .history/2016/09/* |sort -n| uniq
    
      export HISTFILE="${HOME}/.history/$(date -u +%Y/%m/%d.%H.  %M.%S)_${HOSTNAME}_$$"
      export HISTSIZE=
      export HISTCONTROL=ignoreboth
      export HISTCONTROL=erasedups
      export HISTTIMEFROMAT="%d/%m/%Y-%H:%M:%S"
      #export PROMPT_COMMAND='history -a'
      export HISTIGNORE='&:bg:fg:clear:ls:pwd:history:exit:make*:* --help:'
      export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
      histgrep () 
      {
      grep -r "$@" ~/.history
      history | grep "$@"
      }

~~~
beernutz
There may be a typo in in this line

export HISTTIMEFROMAT="%d/%m/%Y-%H:%M:%S"

should HISTTIMEFROMAT be HISTTIMEFORMAT ?

------
jgresty
Here is my lot

    
    
      # setting common options
      alias cp='cp -iv'
      alias mv='mv -iv'
      alias rmdir='rmdir -v'
      alias ln='ln -v'
      alias ls='ls --color=auto --human-readable --group-directories-first --classify'
      alias grep='grep --color=auto'
    
      # shortcuts
      alias e=vim
      alias music=ncmpcpp
      alias g='git status'
      alias gp='git push'
    
      # show pretty git diff
      alias gitdiff='git difftool -y -x "colordiff -y -W $COLUMNS" | less -R'
      # go to root git directory
      alias cdgit='cd $(git rev-parse --show-toplevel)'
      # view csv files in columns
      alias csv='column -s, -t'
      # activate python venv
      alias v='source ./venv/bin/activate'
    
      # show weather
      alias weather='curl wttr.in/Manchester'
      # get my calendar
      alias c='gcalcli --calendar <redacted> --monday calw'
      # alternate view of calendar
      alias agenda='gcalcli --calendar <redacted> agenda `date --iso-8601`T08 `date --iso-8601`T15'
    
      # rot13 some text
      alias rot13="tr '[A-Za-z]' '[N-ZA-Mn-za-m]'"
    
      # I always forget how to echo status code
      alias exitcode='echo $?'
    
      # make directory and enter it
      mdc() { mkdir -p "$@" && cd "$@"; }
      # create a file and make git track it
      ga() { touch "$@" && git add "$@" }
      # open a twitch stream in mpv
      twitch() { livestreamer --player "mpv -" "http://twitch.tv/$@" best }
      # set terminal window title
      title() { print -Pn "\e]2;$@\a" }
      # open a file with less or a directory with ls
      l() { if [ -f "$1" ]; then less "$1"; else ls "${1:-`pwd`}"; fi }

~~~
antichris
livestreamer is dead, long live streamlink

------
exogen
Since I'm working in git repos the majority of the time, I type these hundreds
of times per day:

    
    
        alias s="git status"
        alias d="git diff"
    

I prefer looking at this stuff in a terminal rather than an IDE. Reducing them
to a single character just feels so good. Note: not a git alias like "git s",
literally just the single character "s" in Bash itself.

And coming in third:

    
    
        alias ..="cd .."

~~~
chrismorgan

      alias ..="cd .."
    

If you use zsh, typing a directory name changes to it automatically. It’s
almost always a very delightful thing.

~~~
rossy
Bash has this as well

    
    
      set autocd

~~~
enriquto
that would be rather

    
    
        shopt -s autocd

~~~
emmelaich
Yeppity.

> _autocd If set, a command name that is the name of a directory is executed
> as if it were the argument to the cd command. This option is only used by
> interactive shells_

------
iwalton3
This lets you easily search your command history by typing the beginning of a
command and pressing the up arrow.

    
    
        bind '"\e[A": history-search-backward'
        bind '"\e[B": history-search-forward'
    

This one automatically lists the files in the current directory, but limits
the number of lines.

    
    
        function cd {
            builtin cd "${@}"
            if [[ "$(stat -c "%b" .)" -lt "100" ]]
            then
            if [ "$( ls -C -w $COLUMNS | wc -l )" -gt 30 ] ; then
                ls -C -w $COLUMNS --color=always | awk 'NR < 16 { print }; NR == 16 { print " (... snip ...)" }; { buffer[NR % 14] = $0 } END { for( i = NR + 1; i <= NR+14; i++ ) print buffer[i % 14] }'
            else
                ls
            fi
            fi
        }

~~~
antoineMoPa
The first one is pretty much CTRL+R (reverse incremental search)

------
thiht
Workspace management:

    
    
        export WORKSPACE="$HOME/workspace"
        alias ws='cd $WORKSPACE && ls'
    

History related commands:

    
    
        alias h="fc -li 1"  # like `history` but with dates
    
        # Which commands do I use the most?
        alias histstats="history | awk '{CMD[\$2]++;count++;}END { for (a in CMD)print CMD[a] \" \" CMD[a]/count*100 \"% \" a;}' | grep -v './' | column -c3 -s ' ' -t | sort -nr | nl |  head -n10"
    

Golang:

    
    
        alias gopath='cd $GOPATH/src && tree -dL 3'
    

Git:

    
    
        # --no-pager is underrated
        alias glnp="git --no-pager log --oneline -n30"
    

Misc:

    
    
        # Have I been pwned?
        # usage: `hibp email@example.com`
        hibp() {
            curl -fsS "https://haveibeenpwned.com/api/v2/breachedaccount/$1" | jq -r 'sort_by(.BreachDate)[] | [.Title,.Domain,.BreachDate,.PwnCount] | @tsv' | column -t -s$'\t'
        }
    
        # Weather
        alias weather='curl wttr.in/$CITY'

~~~
2T1Qka0rEiPr
What shell are you using? I'm using bash and don't have the `i` argument in my
version of `fc`

~~~
thiht
I'm using zsh

------
zanbaldwin

        # ============= #
        # Bash-specific #
        # ============= #
        alias sudo="sudo --preserve-env"
        # Up & down map to history search once a command has been started.
        bind '"\e[A":history-search-backward'
        bind '"\e[B":history-search-forward'
        alias tmux="tmux attach || tmux new"
        alias fuck='sudo "$SHELL" -c "$(history -p !!)"'
        alias fucking="sudo"
        # ========================================================= #
        # GnuPG SSH Authentication                                  #
        # ========================================================= #
        # - Install "gnupg2" and "scdaemon".                        #
        # - Add "enable-ssh-support" to "~/.gnupg/gpg-agent.conf"   #
        #   - Or copy existing config from this repository          #
        # - Find [A]uthentication keygrips "gpg -K --with-keygrip"  #
        # - Add appropriate keygrips to "~/.gnupg/sshcontrol"       #
        # ========================================================= #
        which gpgconf 1>/dev/null 2>&1
        if [ $? -eq 0 ]; then
            export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
            gpgconf --launch gpg-agent
        fi

~~~
adontz
You can use "tmux new -A" instead of two commands

------
aliencat
This one is pretty useful!

Open current OSX Finder directory in Terminal:

    
    
      cdf () {
            target=`osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)'`
            if [ "$target" != "" ]
            then
                    cd "$target"
                    pwd
            else
                    echo 'No Finder window found' >&2
            fi
    }

~~~
esseti
can't you just wite "cd" and drag the folder into the terminal?

~~~
yesenadam
Yes, but that's a royal pain. 'cdf' are 3 adjacent keys.

------
krmbzds
This is the function I use to set PATH:

    
    
      function path {
        if [[ -d "$1" ]] ; then
          if [[ -z "$PATH" ]] ; then
            export PATH=$1
          else
            export PATH=$PATH:$1
          fi
        fi
      }
    
      export PATH=''
    
      path ~/.homebrew/sbin
      path ~/.homebrew/bin
      path /usr/local/sbin
      path /usr/local/bin
      path /usr/sbin
      path /usr/bin
      path /sbin
      path /bin
    

It simplifies the syntax.

I also like to keep vim swaps/backups/history in a centralized place (.vimrc):

    
    
      set directory=~/.vim/swaps      " centralized swaps
      set backupdir=~/.vim/backups    " centralized backups
      set undodir=~/.vim/undo         " centralized undo history
    

I don't like leaving ~clutter in random folders.

I also like to alias sl to ls :)

    
    
      alias sl='ls'
    

Other than that, the least you have to configure the better.

You can check my dotfiles here:
[https://github.com/krmbzds/dotfiles](https://github.com/krmbzds/dotfiles)

------
luord
A simple but effective one:

    
    
      function lie {
        if [[ "$1" == "not" ]]
        then
          unset GIT_AUTHOR_DATE
          unset GIT_COMMITTER_DATE
          return 0
        fi
        export GIT_AUTHOR_DATE="$1"
        export export GIT_COMMITTER_DATE="$1"
      }
    

My employers don't quite need to know how much I procrastinated in that
particular task :P

------
timrichard
On Linux I use zsh, but these should translate.

Some of my favourite recent ones...

List most recently modified files from the current directory and any below it.
Helps remind me what I was working with when I don't ssh into a box regularly
:

    
    
      alias changedfiles="find . -type f -print0 | xargs -0 stat --format '%Z :%z %n' | sort -nr | cut -d: -f2- | head -n 20"
    

[ Need to tweak that sometime for BSD find on MacOSX, but I use it primarily
on Linux ]

Before backing up from a Unix-typical filesystem to an ExFAT volume attached
by USB, find problematic characters in filenames from the current directory
and any below :

    
    
      function badnames {
    	find . -name '*[?<>\\:*|\"]*'
      }
    
    

A big favourite on volumes with deeply nested directory structures. My
favourite technique for a quick directory find and switch.

If you use FZF, this will show all directories (not files) from the current
directory downwards. You can do an incremental fuzzy search by starting to
type, and quickly change to that directory by pressing Enter when the desired
one is highlighted.

    
    
      function fd() {
    	local dir
    	dir=$(find ${1:-.} -path '*/\.*' -prune -o -type d -print 2> /dev/null | fzf +m) && cd "$dir"
      }
    

Love that one. As 'fd' is right under the fingers on the home row, the
directory search and switch can look like magic when used quickly as part of
the workflow.

------
trulyrandom
My most used alias would be:

    
    
      alias fuck='sudo $(history -p !!)'
    

It runs the previous command as root.

~~~
pvinis
I like that. I'll borrow it, but I'll rename it to 'damn', as 'fuck' it
dedicated to
[https://github.com/nvbn/thefuck](https://github.com/nvbn/thefuck).

------
K0nserv
All of my various git alises. I especially like `goops` which is very useful
if you just pushed some code and realised you missed something.

[https://github.com/k0nserv/dotfiles/blob/7721559be40bba09cd8...](https://github.com/k0nserv/dotfiles/blob/7721559be40bba09cd89b9243907df254999cfdd/files/zshrc.symlink#L16-L24)

    
    
       alias gs="g status"
       alias glff="git pull --ff-only"
       alias glffc="git pull origin \$(current_branch) --ff-only"
       alias glc="git pull origin \$(current_branch)"
       alias gpc="git push origin \$(current_branch)"
       alias gpcfl="git push origin \$(current_branch) --force-with-lease"
       function goops { git add -A "$@" && git commit --amend --no-edit && gpcfl }
       alias gbr="git branch -r"
       alias grm="git branch --merged | grep -v \"\*\" | xargs -n 1 git branch -d"
       function mkb() {
           git fetch && git checkout -b "$1" origin/master
       }
    

`mkdataenv` is nice for spinning up a quick Jupyter environment for all data
analysis needs.

[https://github.com/k0nserv/dotfiles/blob/7721559be40bba09cd8...](https://github.com/k0nserv/dotfiles/blob/7721559be40bba09cd89b9243907df254999cfdd/files/zshrc.symlink#L74-L82)

    
    
        function mkdataenv() {
            mkvirtualenv --python /usr/local/bin/python3 $1
            workon $1
            mkdir "$1"
            cd $1
            pip install pandas jupyter numpy matplotlib seaborn
            pip freeze > requirements.txt
           jupyter notebook
        }

~~~
0x00101010
git aliases is best done with git itself, e.g. my favorite git alias is `git
alias`, which lists all my git aliases.

    
    
      alias.alias config --global --get-regexp ^alias
    

I really like blameconflict:

    
    
      alias.blameconflict blame -L '/^<<<</,/^>>>>/'

~~~
K0nserv
I've never liked git aliases, at least not for things I do frequently.

~~~
0x00101010
With Z-Shell git aliases have tab completion which is really nice. My workflow
often involves something like

    
    
      g fp # git fetch --prune
      ...
      g rb origin/master master # rebase
      g co -
    

A lot of tab and very few keys in general when working with git.

My favorite aliases in this context are

    
    
      alias wow=git
      alias such=git
      alias many=git
      alias awesome=git
      alias much=git

------
Tepix
Here's a function you can use to generate a strong printable password on the
fly:

    
    
        function gen_passwd () {
            openssl rand 150 |\
            tr -dc  '[:graph:]' |\
            cut -c 1-${1:-13}
        }
    

The default password length is 13 characters but you can pass a different
length parameter instead.

Explanation:

* generate 150 pseudo-random bytes using openssl's rand

* discard non-printable characters

* cut to desired length

Note that it will only use the ASCII character set, if you prefer a solution
that also uses german umlauts (öäüÖÄÜß) or something more exotic like emoji in
your passwords you're on your own.

~~~
esseti
I'm trying to use this in mac shell, but it says `tr: Illegal byte sequence`

~~~
stevekemp
Try setting LC_CTYPE:

    
    
      env LC_CTYPE=C tr ..

------
saagarjha
I use bash, but I like the zsh feature where you could type "cd -n" and go
back n entires in your "directory stack", so I made my own version as a
function. It's probably subtly broken in some way, since it's bash, but it
works relatively well for me:

    
    
      cd() {
      	# Set the current directory to the 0th history item
      	cd_history[0]=$PWD
      	if [[ $1 == -h ]]; then
      		for i in ${!cd_history[@]}; do
      			echo $i: "${cd_history[$i]}"
      		done
      		return
      	elif [[ $1 =~ ^-[0-9]+ ]]; then
      		builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
      		return 
      	else
      		builtin cd "$@" || return # Bail if cd fails
      	fi
    	# cd_history = ["", $OLDPWD, cd_history[1:]]
      	cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
      }
    

Other than that, I doubt there's much that would be generally useful to
anyone.

~~~
Dagger2
Funnily enough, I did the exact same thing but for zsh's two-argument cd:

    
    
      cd() { if [[ -n "$2" && "$1" != "--" ]]; then builtin cd "${PWD/"$1"/"$2"}"; else builtin cd "$@"; fi; };
    

It's niche functionality, but super useful when you hit its niche:

    
    
      user@machine:/usr/src/linux-kbuild-4.9/scripts/mod$ cd 4.9 4.8
      user@machine:/usr/src/linux-kbuild-4.8/scripts/mod$ 
    

I'll leave combining these two as an exercise for the reader.

------
ashelmire
This one I use daily without thinking about it - it shares my bash history
between screens and sessions on a given machine and extends it (grabbed from
some corner of the internet):

    
    
        # shares history between tabs with prompt_command
        HISTSIZE=9000
        HISTFILESIZE=$HISTSIZE
        HISTCONTROL=ignorespace:ignoredups
    
        _bash_history_sync() {
          builtin history -a         #1 appends command to histfile
          HISTFILESIZE=$HISTSIZE     #2 sets max size
          builtin history -c         #3 clears current session history
          builtin history -r         #4 reads the updated histfile and makes that the current history
        }
    
        history() {                  #5 overrides build in history to sync it before display
          _bash_history_sync
          builtin history "$@"
        }
    
        PROMPT_COMMAND=_bash_history_sync
    

Sometimes I forget the name of git branches I've worked on lately. This
displays them with dates, most recent at the bottom:

    
    
        git_branch_dates() {
          git for-each-ref --sort=authordate --format '%(authordate:iso) %(align:left,25)%(refname:short)%(end) %(subject)' refs/heads
        }
    

Because I hate typing:

    
    
        # for rails migrations and keeping test updated
        alias migrate="rake db:migrate && RAILS_ENV=test rake db:migrate"
    

Something I should use more to track things I've done lately - this opens up
vim at the end of a file in your home dir called did.txt, appends the date and
puts cursor at the last line:

    
    
        # didfile setup
        alias did="vim +'normal Go' +'r!date' ~/did.txt"
    

Because sometimes you want to sudo an alias:

    
    
        # trailing space in value expands aliases that come after, see: http://www.linuxcommand.org/lc3_man_pages/aliash.html
        alias sudo='sudo '
    

And displaying the git branch in the prompt:

    
    
        # this gets the git branch to display when I cd into a git repo
        parse_git_branch() {
            git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
        }
    
        export PS1="\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\[\033[32m\]\$(parse_git_branch)\[\033[00m\]\$ "
    

Because I often want to check recent files:

    
    
        alias llth='ls -hFlat | head'

~~~
mttyng
> this gets the git branch to display when I cd into a git repo

It's early and I'm lazy... will this always parse the branch upon entering any
git directory?

~~~
mttyng
Edit: ugh, nevermind it _is_ early. I know that answer. Thanks for the cool
functions.

~~~
ashelmire
Hope you find them as useful as I have!

------
yakshaving_jgt

      function remac {
        sudo /System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -z
        sudo ifconfig en0 ether $(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//')
        sudo networksetup -detectnewhardware
        echo $(ifconfig en0 | grep ether)
      }
    

Explanation: [https://jezenthomas.com/free-internet-on-
trains/](https://jezenthomas.com/free-internet-on-trains/)

Also, when I need to share a code snippet I pipe it to this:

    
    
      alias ix="curl -F 'f:1=<-' ix.io"
    

Oh, and perhaps the most important part of my .vimrc:
[https://github.com/jezen/dotfiles/blob/master/.vimrc#L160](https://github.com/jezen/dotfiles/blob/master/.vimrc#L160)

------
carl-erwin
One thing I do is to put this snippet in .bashrc or .profile

    
    
      for i in ${HOME}/.bash.d/*.sh
      do
        if [ -r ${i} ] ; then
            . ${i}
        fi
      done
      

And drop some custom scripts in ${HOME}/.bash.d/ like alias.sh, env.sh

(my common .bash.d scripts are saved in a git repository)

~~~
ob6160
Whoa, I know someone who does exactly this. Is this a common pattern?

Unless you're him!

~~~
nailer
.d is a common Unix include directory pattern. See cron.d, xinetrc.d, conf.d
etc. Packages can just add/remove things to the include dir rather than
modifying the main config.

------
stevebmark
Annoyingly not built in, pathadd and pathrm to make sure re-sourcing your
bashrc doesn't hose your environment.

    
    
        pathadd() {
            newelement=${1%/}
            if [ -d "$1" ] && ! echo "$PATH" | grep -E -q "(^|:)$newelement($|:)" ; then
                if [ "$2" = "after" ] ; then
                    PATH="$PATH:$newelement"
                else
                    PATH="$newelement:$PATH"
                fi
            fi
        }
    
        pathrm() {
            PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
        }

------
ivan_ah
This is pretty useful for downloading mp3s of songs from youtube:

    
    
       alias getmp3="youtube-dl -x --audio-format mp3 "
    

usage

    
    
       getmp3 https://www.youtube.com/watch?v=<id-of-some-nice-tune>
    
    

(You'll need to to `pip install youtube_dl` first and probably have `ffmpeg`
installed too)

------
niuzeta
Out of everything I like this little alias the most:

    
    
       cls="clear; ls"
    

It harkens back to DOS. Clearing the screen followed by ls happens
surprisingly often, if not just to start things in "clean slate". I'm quite
fond of it.

~~~
hobos_delight
My muscle memory is to set on CTRL+L, ls. But I like it, and the call back to
DOS days :)

------
niyazpk
Not as fancy as other tips here, but I bet this is really time saving in the
long run for most developers.

My core work is alway around ~10 directories, which are mostly code packages.
As soon as I start working on a project/team, I create aliases for
directories. They take the form:

    
    
      alias agg="cd /ws/ProjectName/src/PackageName/ &&
                 echo -n -e '\033]0;PackageName\007' &&
                 tab-color-devil-blue"
    

The first part of course navigates to the directory. The second part sets the
tabName of my iTerm to the package name. The last part sets the background
color of the tab to something unique for the package. This makes it easy to
spot the right tab when I have like 10 iTerm tabs open.

In case you want to see the definition of the last part:

    
    
        set_tab_color() {
            echo -ne "\033]6;1;bg;red;brightness;$1\a"
            echo -ne "\033]6;1;bg;green;brightness;$2\a"
            echo -ne "\033]6;1;bg;blue;brightness;$3\a"
        }
        tab-color-devil-blue() { set_tab_color 34 112 147 }
    

Tested only in iTerm.

~~~
wingerlang
In my previous setup, I had a function that displayed a menu when I started
bash, listing all my "main" directories. So each time you started a session
you just had to press 1-7 to go where you wanted.

~~~
niyazpk
That is a great idea. Thank you!

~~~
wingerlang
Definitely save me some time and effort. The only issue I had was that
sometimes when I wanted to use bash from, like, another app it would start the
menu so it wouldn't work to use it from them. I'm sure it can be worked around
but it was never a real issue so I didn't work on it.

Here is the code I had
[https://gist.github.com/jontelang/c6317bf14c527d2a89f1efd5d0...](https://gist.github.com/jontelang/c6317bf14c527d2a89f1efd5d0558f73)
and I put this straight into my .bash_profile and it runs automatically when
the shell starts.

------
fortenforge

      alias search='set -f;search';search() { find . ${2:+-name "$2"} -type f -print0 | xargs -0 grep --color=auto "$1"; }
    
    

Recursively searches the files in the current directory for string matches.
You can optionally provide a second glob argument to restrict what files to
search. This is basically a dumber version of ack-grep, but I wrote it before
I learned about ack.

------
chrismorgan
The one I use most often is undoubtedly `g` for `git`. Then I have many
aliases inside Git for all kinds of regularly done things, quite a few lifted
from Mercurial and then extended; some just shorter names (ci = commit, glog =
log --graph) and some more advanced like these three:

    
    
      fixup = "!f() { TARGET=\"$(git rev-parse \"$1\")\"; shift; git commit --fixup=\"$TARGET\" \"$@\" && git -c core.editor=true rebase --interactive --autostash --autosquash \"$TARGET^\"; }; f"
      in  = "!f() { case \"x$1\" in x-*|x) branch=;; *) branch=\"$1\"; shift;; esac; git glog \"$branch..$branch@{upstream}\" \"$@\"; }; f"
      out = "!f() { case \"x$1\" in x-*|x) branch=;; *) branch=\"$1\"; shift;; esac; git glog \"$branch@{upstream}..$branch\" \"$@\"; }; f"
    

My most recent addition to my shell profile (a couple of weeks ago) enhances
ts from the moreutils package. ts provides timestamps (relative to process
execution or absolute) at the start of each line of stdout. My enhancement
makes it cover stderr as well, so that stdout lines get a green timestamp and
stderr lines get a red timestamp. Due to how interlacing works, and the fact
that I commonly pair this with concurrency in the form of `make -j8`, it’s not
perfect (can end up with a line possessing both green and red timestamps, and
then none on the next line), but it’s still _really_ helpful. I just need to
get round to adding something to it to make programs still colour their own
output. `script` can do that, I think.

It’s currently this shell function:

    
    
      ts-fancy() {
        ((("$@" 2>&1 1>&3 3>&-) | ts -s "^[[91m[%H:%M:%.S]^[[m") 3>&1 1>&2) | ts -s "^[[92m[%H:%M:%.S]^[[m"
      }
    

(Each ^[ shown there is a literal ␛.) ts-fancy was the temporary name I gave
it at first, haven’t renamed it to anything more permanent yet, so it’ll
probably stay that way forever.

Usage, `ts-fancy make -j8 --keep-going` and things like that. It’s proving
really helpful when figuring out what’s slow in something that verbosely logs,
and also in highlighting error output mixed in with normal output.

This exercise made me wish for a smarter terminal that kept track of
timestamps and whether output went to stdout or stderr itself (at the
character level, even, to resolve the problems of this line-based approach). I
shouldn’t have to do this, and you know how often you think _after_ the fact
that it’d be nice to have timestamps?

~~~
delian66
Very nice! Thanks you for sharing this!

It really seems very useful to have timestamps for every line of output.

I have tried to approximate this in the past, by setting my bash prompt to be:

    
    
        export PS1='\[\e[00;37m\]$?\[\e[0m\]\[\033[1;32m\]\[\033[1;32m\][\t]\[\033[1;41m\]\u\[\033[1;41m\]@\[\033[1;41m\]\h:\[\033[0m\] \[\033[1;32m\]\w\[\033[0m\] \$ '
    

... which shows the previous command exit code, the current time (with second
resolution) and the ordinary stuff like username host and working dir, so it
looks somewhat like:

    
    
        0[21:20:18]delian66@mypc: ~/Work $ slow_command
        ....
        0[21:22:19]delian66@mypc: ~/Work $

~~~
chrismorgan
I contemplated that for a while a few years back, but decided against it for
several reasons:

① I didn’t like an overly-long prompt. On my own machine I already exclude
username and hostname, so it’s just `~/Work$ `. (Sometimes PWD gets a bit
long, but generally not too much.)

② It was fairly rare that I actually cared about such a timestamp in any
way—if I did, it was normally about time taken, and so I could pipe the
program through `time` (this was before I discovered `ts` when figuring
“someone _must_ have made a program to do this” a couple of weeks ago when
preparing to optimise a build process at work), or execute `date; …; date`.

③ Such a timestamp is only written when the prompt is output, rather than when
the program is executed (there may be a sane way to have it work otherwise—I
didn’t investigate in any way thoroughly—but my initial thoughts suggested any
hacky attempt to move the cursor after the fact would interact badly with
commands that cause the command line to span multiple lines). This made it
useless for well over 90% of the cases when I might have benefited from it
(retroactive timing of the duration of a command, rather than at what o’clock
I… _probably_ did something).

I return to the desire for a very mildly intelligent terminal that notes when
characters were written to screen when not in raw mode, for optional viewing.

~~~
delian66
I've just made this [0], based on your idea (differently colored timestamps
for both stderr and stdout).

It just spawns the actual command in a sub process, but may be the output may
be more ordered than that of a pipe of ts commands.

[0]
[https://github.com/spytheman/gostamp](https://github.com/spytheman/gostamp)

------
rgomez
Cherry-picking some of them:

    
    
        # Show Disk Use of subdirectories, sort by size
        alias duss="sudo du -d 1 -h | sort -hr | egrep -v ^0"
    
        # Cheatsheet autogenerated from i3 configuration file
        alias i3cheatsheet="egrep ^bind ~/.i3/config | cut -d ' ' -f 2- | sed 's/ /\t/' | column -ts $'\t' | pr -2 -w 145 -t | less"
    
        # Show mount information in a nice format
        alias mountt="mount | column -t | sort"
    
        # Show remaining dirty bytes while coping to a file, very useful in XFCE not sure in other enviroments
        alias watchdirty="watch grep -e Dirty: -e Writeback: /proc/meminfo"
    
        
        # Bookmark directories ej. "bm a" "go a" etc
        go() { eval dir=\$$1; cd "$dir"; }
        bm() { eval $1=$(pwd); echo "`set | egrep ^[a-z]+=\/`" > ~/.bookmarks; }
        test -f ~/.bookmarks && source ~/.bookmarks
    
        # I use this one all the time, combined find+grep, f.e. fgr "Class" "*.cpp" "-l" (2nd and 3rd parameters optional"
        function fgr {
                NAM=""
                GREPTYPE="-i -H"
                if [ -n "$1" ]; then
                        test -n "$2" && NAM="-name \"$2\""
                        test -n "$3" && GREPTYPE=$3
                        CMMD="find . $NAM -not -path '*/\.*' -exec egrep --colour=auto $GREPTYPE \"$1\" {} + 2>/dev/null"
                        >&2 echo -e "Running: $CMMD\n"
                        sh -c "$CMMD"
                        echo ""
                else
                        echo -e "Expected: fgr <search> [file filter] [grep opt]\n"
                fi
        }

------
johncoltrane
A well crafted $CDPATH helps me jump from project to project and from
directory to directory within a project without having to type many ../:

    
    
        CDPATH=./:~/:~/Documents/:[...]
    

I often grep/ag stuff only to think afterwards that I should have done that
from Vim, so I have this to rerun the previous command and feed its output to
Vim's quickfix:

    
    
        vimq() {
        	vim -q <($(fc -nl -1))
        }
    

Speaking of Vim, this one lets me open an arbitrary file from the current
project in Vim without having to glob:

    
    
        vimf() {
        	vim +find\ **/*$1
        }
    

Create a directory and cd to it:

    
    
        mkcd() {
        	mkdir -p "$*"
        	cd "$*"
        }
    

It's not in my .bash_profile but I use this little command all over the place
to get my IP address (and I need my IP address a lot):

    
    
        #!/usr/bin/env sh
    
        SYSTEM=$(\uname | \tr /a-z/ /A-Z/ | \cut -c-5)
    
        # MacOS
        if [ "$SYSTEM" = "DARWI" ]; then
        	\ifconfig | \sed '/vboxnet/{N;N;d;}' | \grep 'inet ' | \grep -v '127.0.0.1' | \awk '{print $2}' | \tr '\n' '-' | \sed 's/-.*//' | \tr -d '\n'
        	\exit 0
        fi
    
        # Linux
        if [ "$SYSTEM" = "LINUX" ]; then
        	\ip route get 1 | \awk '{print $NF}' | \tr -d '\n'
        	\exit 0
        fi
    
        # MINGW/CYGWIN on Windows
        if [ "$SYSTEM" = "MINGW" -o "$SYSTEM" = "CYGWI" ]; then
        	\ipconfig | \grep 'IPv4' | \awk '{print $NF}' | \tr -d '\n'
        	\exit 0
        fi

~~~
yesenadam
(It works, but..) What are all those backslashes for?

~~~
johncoltrane
I use them to escape the first character of the command name, which has the
effect of using the actual command and not an alias. In looking for a link to
give you some background I found out that this is limited to interactive
shells so those backslashes are just me not understanding what I do.

~~~
yesenadam
Ohh I didn't know that. Well...I've aliased a few programs to use a different
version than the default, and redefined a few commands, so just prefixing "\"
will get the original one. Very handy, thanks!

------
robohoe
Here is mine:

    
    
      # misc
      alias mount="mount | column -t"
      alias ports="netstat -tulanp"
      alias vmstat="vmstat -w"
      alias ed="ed -p '>>> '"
      # genpass
      function genpass() { head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c $1; echo; }
    
      # git stuff
      alias gitpretty="git log --graph --oneline --decorate --all"
      alias gitprettyall="git log --oneline --decorate --all --  graph --stat"
      alias gfiles="git show --pretty='' --name-only $1"
      alias gitstat="git log --stat"
      alias gitchangelog="git log --oneline --no-merges ${1}..HEAD"
      alias gittopcontrib="git shortlog -ns"
      alias gitdiff="git difftool $1"

------
insertnickname
I use fzf [0] with zsh. I frequently use the Ctrl-T and Ctrl-R commands for
finding files and searching history, respectively. Ctrl-R without fzf is great
too, but with fzf you can see more of the history than just the currently
selected entry. I hardly do `history | grep` anymore.

I've also been using trash-cli [1] for years with `rm` aliased to `trash-put`.
It's saved me a handful of times when I've carelessly `rm`d something I
shouldn't have.

[0] [https://github.com/junegunn/fzf](https://github.com/junegunn/fzf)

[1] [https://github.com/andreafrancia/trash-
cli](https://github.com/andreafrancia/trash-cli) \- Command Line Interface to
FreeDesktop.org Trash.

------
xiroux
alias shrug='echo -n "¯\\_(ツ)_/¯" | xclip -selection clipboard && echo
"\"¯\\_(ツ)_/¯\" copied to clipboard!"'

alias YOLO='aurman -Syyu --noedit --noconfirm'

------
asdojasdosadsa
I have many, but one above all:

I've tried several different, SimpleNote, KeepNote, EverNote... and so on. I
have come to a conclusion, that using the default iOS note app is enough for
me. Using paper notes while @lectures and rewriting them sometimes to Notes.
I'm also using another method of note taking, which I prefer more, but which
is not always accessible on the go. I stumbled upon a script here and modified
it a little. (changed vim to nano and added some other):

    
    
        #! /bin/bash
        fpath=$HOME/notes.md
    
        if [ "$1" == "cat" ]; then
            cat "$fpath"
            exit 0
        elif [ "$1" == "rg" ]; then
            rg "$2" "$fpath"
        elif [ "$1" == "nano" ]; then
            nano "$fpath"
        elif [ "$1" == "--help" ]; then
            printf 'Commands: \n-----------------------------------------------\n
            $ notes \n
            $ notes --help\t\t--\tdisplay this help\n
            $ notes date\t\t--\tadd date row to notes\n
            $ notes <text>\t\t--\tadd new entry \n
            $ notes cat\t\t--\tprint notes using cat\n
            $ notes rg <pattern>\t--\tripgrep notes\n
            Remember to use #tags (for easier grepping)!\n\n'
        elif [ "$1" == "date" ]; then
            {
            echo ''
            echo '# '"$(date +"%m-%d-%Y-%T")"
            echo '-'
            } >> "$fpath"
        elif [ "$1" == "" ]; then
            less +G "$fpath"
        else
            {
                echo ''
                echo "$@"
                echo ''
            } >>"$fpath"
        fi
    
    

In short, writing $ notes prints out displays the notes and writing $ notes
<text> appends a new line. This is extremely powerful because of it's
simplicity and easy accessibility in terminal (where I spend most of the time
anyway)

From thread: Ask HN: Favorite note-taking software?
[https://news.ycombinator.com/item?id=17532094](https://news.ycombinator.com/item?id=17532094)

------
toupeira
Some Git aliases I use constantly, with a rebase-heavy workflow:

    
    
        di = diff
        dc = diff --cached
    
        ap = add -p
        unstage = reset HEAD -p
        discard = checkout -p
    
        ci = commit -v
        ca = commit -va
        amend = commit -v --amend
        reword = commit -v --amend --only
        extend = commit -v --amend --no-edit
    
        ri = rebase -i
        rem = rebase master
        rim = rebase -i master
        red = rebase development
        rid = rebase -i development
        continue = rebase --continue
        skip = rebase --skip
    
        pu   = push -v --progress
        poof = push -v --progress --force-with-lease
        pusu = -c push.default=current push -v --progress --set-upstream

------
adamnemecek
I use sd (kinda like cd) when working with on mac with finder. With sd, you
can select a file in finder, CMD+C and sd filepath.txt. The nice thing is that
it goes to the same directory as the file so you don't have to delete the last
part of the path manually. If you are sd-ing into a directory, it behaves like
cd.

    
    
        sd () {
            if [ -f "$*" ]
            then
                    cd "$(dirname "$*")"
            else
                    cd "$*"
            fi
        }
    

Also cwd which is like pwd but it also copies the current path to your
clipboard.

    
    
        cwd='pwd | tr -d "\n" | pbcopy && pwd'

------
ragebol

        alias continue-branch='charm $(git diff master --name-only)'  # Open all files changed in the current branch wrt master in PyCharm
    
        function record-window {
    	recordmydesktop --windowid=$(wmctrl -l | grep $1 | awk '{print $1}') -o ~/Videos/$1_$(date +"%Y_%m_%d_%H_%M_%S").ogv
        }
    
        alias ping='grc ping'
        alias ifconfig='grc ifconfig'
        alias netstat='grc netstat'
    
    

These last three use the awesome 'grc' output colorizer

------
cik
_dynamic_ssh_creator() {

    
    
        for i in `ls ~/.ssh/keys|grep -v ".pub"|grep -v "id_dsa$"`; do
    
            cmd="$i"ssh
    
            func="function $cmd {"
    
            func="$func ssh -i ~/.ssh/keys/$i \$*;"
    
            func="$func }"
    
            eval $func
    
        done
    

}

_dynamic_ssh_creator

I have so many SSH keys that I can't be arsed to maintain an SSH config -
especially when my brain is faster at it. This allows me to type <keyname>ssh
and just live my life.

------
xelxebar
I like the ix.io pastebin, since it has a nice rest interface and the url is
concise. I have a wrapper function that lets you run

    
    
        ix [<path>]
    

and will sumbit the content of the supplied path, or stdin if no path is
given.

Here's function at said pastebin
([http://ix.io/1yiG/sh](http://ix.io/1yiG/sh)), and in raw form below:

    
    
        ix() {
        	curl=$(command -v curl)
        	[ -f "$HOME/.netrc" ] && curl="${curl} --netrc"
        
        	while getopts ":d:i:n:e:" opt; do
        		case "${opt}" in
        			d) ${curl} --request DELETE "ix.io/${OPTARG}"; return;;
        			i) curl="${curl} --request PUT"; id="${OPTARG}";;
        			n) curl="${curl} --form read:1=${OPTARG}";;
        			e) curl="${curl} --form ext:1=${OPTARG}";;
        			:) error "Expected argument: -${OPTARG}"; return 1;;
        			*) echo 'Usage: ix [-d ID] [-i ID] [-n N] [<options>]';
        				return;;
        		esac
        	done
        	shift $((OPTIND - 1))
        	unset -v OPTIND OPTERR
        
        	if [ -t 0 ]; then
        		filename="$1"; shift
        		if [ "$filename" ]; then
        			${curl} --form f:1=@"$filename" "${@}" "ix.io/${id}"
        			return
        		fi
        		echo "^C to cancel, ^D to send."
        	fi
        
        	${curl} --form f:1='<-' "${@}" "ix.io/${id}"
        
        	unset -v curl opt id filename
        }

------
rcdwealth
In ~/.bash_functions

    
    
      $ loz QUERY
    

will give the password from the ~/.passwords flat text database, last password
is valid one.

    
    
      $ lozinka
    

will ask for questions and enter it into ~/.passwords

I suggest chattr +a ~/.passwords so that file cannot be deleted, only
appended.

    
    
      function loz () {
                PASSWORDS=~/.passwords;
                if [[ "$1" ]]; then
                    /bin/grep -i --color=auto "$1" $PASSWORDS;
                else
                    echo "No query given."
                fi
       }
    
      function lozinka () {
           passwords=~/.passwords
           echo -n "Hostname:"; read hostname;
           echo -n "Service:"; read service;
           echo -n "Username:"; read username;
         echo -n "Email:"; read email;
         password=$(pwgen -n -n -n -s 20 1)
         echo -n "Password (${password}):"; read password1;
         if [[ $password1 ]]; then
             password=$password1
         fi
         if [[ ( $username || $email ) && $password ]]; then
             line=$(join_by : $hostname $service $username $email $password);
             echo $line >> $passwords;
             tail -n1 $passwords;
         else
             echo "Nothing recorded as there is no username or email";
         fi
       }

------
ikornaselur
I have few on my MBP that I use a lot

# CD to the root of the current git project

    
    
        alias ,,='git rev-parse --git-dir >/dev/null 2>&1 && cd `git rev-parse --show-toplevel` || echo "Not in git repo"'
    
    

# Put my MBP to sleep in X minutes

    
    
        sleep-in() {echo "Sleeping laptop in $1 minutes..." && sleep $((60 * $1)) && pmset sleepnow}
    

# Check CI status nicely using hub (hub.github.com)

    
    
        function ci {
          unbuffer hub ci-status -v $1 | sed 's/https:.*//'
        }
    

# Rerun the last git command with the suggestion it had

    
    
        alias yup='eval $(fc -ln -1 | sed "s/git/git -c \"help.autocorrect=-1\"/")'
    

# Look up directories for a Makefile and run it - I couldn't find a way to
actually search up directories, so `detect` is my own binary that does that

    
    
        function make {
            if detect Makefile > /dev/null 2>&1 ; then
                LOCATION=$(detect Makefile)
                echo "Makefile found at $LOCATION"
                cd $LOCATION && /usr/bin/make $* && cd - >/dev/null
            else
                echo "Makefile not found"
            fi
        }

------
byuu
Definitely not for everyone, but:

    
    
      set +H
      export HISTIGNORE="&"
      alias reset="printf '\033\143'"
      alias ls="ls --color=never -p -D '%Y-%m-%d %H:%M'"
      alias pmake="gmake -j30"
      PS1="\[\e[0;32m\][\w]$\[\e[m\] "
      history -w
      history -c
    

I turn off history substitution (sometimes ! get into my program arguments and
I don't like surprises), and start with no history on new terminals. I don't
trust myself not to run an rm * from a previous session, open another
terminal, and hit up one too many times.

A little colorization of the terminal prompt, and spicing up of ls output (the
colors actually give me trouble, and often I can't read the dark blue items at
all.)

But most specifically, I adore the reset alias. Unlike clear, it isn't undone
when you scroll up. The built-in reset command takes forever to run and does a
bunch of things I don't want.

HISTIGNORE is my absolute favorite. It doesn't log your last command to
history if it's the same as the one already there. I'll often run make
multiple times to fix compilation errors, and with HISTIGNORE, the command to
run the resulting binary is only ever two up keystrokes away.

~~~
sigi45
I switched to a color schema where this dark blue is gone :-)

------
cddotdotslash
I have some git ones that save me a few thousand key strokes a day.

    
    
      alias gs="git status"
      alias gall="git add ."
      alias gm="git commit"

------
godot
I work at a company with micro services so we have a lot of repos. We use
nodejs and in some cases use different node versions among different services.
Having the prompt show what branch I'm in and what node version I'm on is
quite helpful:

    
    
      PS1="\[\033[01;31m\]Node \`node --version\`: \[\033[01;32m\]\`pwd\` \`git status -sb 2> /dev/null | head -n 1\`\n\[\033[01;34m\]\`date +'%a, %B %-d, %-l:%M:%S%P'\` \[\033[01;31m\]\$ \[\033[00m\]"
    
    

Pruning branches both remote and locally are also very helpful to do in these
alias/functions:

    
    
      function gitpruneremote {
        git remote prune origin
      }
      
      function gitprunelocal {
        git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -D
      }
    
    

Git pulling in every repo:

    
    
      function gitpullall {
        cd ~/yourCodeDir
        find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull \;
      }
    

This one is simple, and was useful in my LAMP dev days, to tail apache logs
with line breaks formatted:

    
    
      function tailerr() {
        tail -f /path/to/errorlog | sed 's/\\n/\n/g'
      }

------
11235813213455

        alias ..='cd ..'
        alias ...='cd ../..'
        alias ....='cd ../../..'
        alias d='docker'
        alias up='docker stack up --with-registry-auth'
        alias node='node --experimental-modules --experimental-repl-await --no-warnings'
        alias net='netstat -tunl'
        alias jurl='curl -sLH "Content-Type: application/json"'
        alias sb='source ~/.bashrc'
        rand() {
          openssl rand -base64 ${1:-15} | tr '+/' '-_' | tr -d '[[:space:]]='
        }
        randomstring() { LC_CTYPE=C tr -dc '[:print:]' < /dev/urandom | dd bs="${1:-16}" count=1 2>/dev/null; echo; }
        serv() { docker run --rm --name "nginx-${1:-8000}" -p "${1:-8000}:80" "${@:2}" -v $PWD:/usr/share/nginx/html:ro caub/nginx-dev; }
    
        npmRegexp='^(i|init|install|link|list|ls|outdated|pack|prefix|prune|publish|r|rb|rebuild|restart|run|start|stop|test|tst|unpublish|up|update)$'
        n() {
          if [[ "$1" =~ $npmRegexp ]]; then 
            npm "$@"
          else 
            npm run "$@"
          fi
        }

------
pgtan
alias lcoate=locate

alias ll="ls -l"

alias ..="cd .."

alias ...="cd ../.."

alias mdd='mkdir $(date -I)'

alias cdd='cd $(date -I)'

alias xt="xtermset -T "

alias dtail="dmesg|tail"

~~~
rrobukef

        alias cdl="cd (ls -ltr1 | grep '^d' | tail -1 | awk '{print $9}');"
    

cd to last directory by date.

------
cgijoe
My most commonly used thing in my profile is this combination git tag, push,
and npm publish using the current version in my package.json file:

    
    
       	np() {
    		PACKAGE_VERSION=$(node -p -e "require('./package.json').version")
    		SHORTVER="v$PACKAGE_VERSION"
    		LONGVER="Version $PACKAGE_VERSION"
    		echo $LONGVER
    		git tag -a "$SHORTVER" -m "$LONGVER" && git push --tags && npm publish
    	}

~~~
11235813213455

        node -p "require('./package.json').version"
    

no need for -e, or also just:

    
    
        jq -r .version package.json

------
yesenadam
I have 'usb' aliased as my main USB's directory.

Making 'cd' more explicit:

    
    
      cd ( ) {
      builtin cd "$@"
      echo "$OLDPWD -> $PWD"
      }
    

Up directory

    
    
      alias ..='cd ../' 
    

This one I use to find bits in my favourite books/essays, which I have in
folders in /books, under e.g. /books/Shakespeare/Macbeth, then search with
'book to be or' etc.

    
    
      book () {
      # Find occurrences of words in texts. Put folders in ~/books, or soft links (ln -s) 
      # Displays only complete words found, not parts of words.
      GREP_COLOR=red
      grep -r -n -i --word-regexp --color -C 1 "$*" ./books/
      echo `grep -r -i "$*" ./books/ | wc -l` occurrences of \"$*\" found, `grep -i -r --word-regexp "$*" ./books/ | wc -l` as a whole word.
      }
    

'dlm' downloads mp4 file from URL in clipboard

    
    
      #!/bin/bash
      #dlm - download mp4 from clipboard URL. usage: 'dlm myfile' downloads myfile.mp4
      #with resume after 5 secs until finish.
      fname=$(pbpaste)
      echo "Download $fname as $1.mp4 : "
      until curl -C - -kLo $1.mp4 "$fname"
      do
            sleep 5
      done

------
vittore
I am using zsh/iterm on my mac so here are mine:

    
    
        # branches that were touched lately 
        nb() {
          git for-each-ref --sort=-committerdate refs/heads/ -- format='%(committerdate:short) %(authorname) %(refname:short)' | head -n 10
        }
    
        # squash!
        squash() {
          if [ -n "$1" ]; then
            git reset --soft HEAD~$1 && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
          fi
        }
    
        # open pr page on github for current branch
        pr () {
          local repo=`git remote -v | grep -m 1 "(push)" | sed -e "s/.*github.com[:/]\(.*\)\.git.*/\1/"`
          local branch=`git name-rev --name-only HEAD`
          echo "... creating pull request for branch \"$branch\" in \"$repo\""
          open "https://github.com/$repo/pull/new/$branch?expand=1"
        }
    
        # check who uses port 
        port() {
          lsof -i tcp:"$@"
        }
    
        # rebases local branch from origin /master and force pushes it
        repush(){
          git fetch origin master
          git stash
          git rebase origin/master
          git push --force
          git stash pop
        }

------
aug-riedinger
Probably too late to get some visibility, but I love this:

    
    
        function my-accept-line() {
          # check if the buffer does not contain any words
          if [ ${#${(z)BUFFER}} -eq 0 ]; then
            # put newline so that the output does not start next
            # to the prompt
            echo
            # check if inside git repository
            if git rev-parse --git-dir > /dev/null 2>&1 ; then
              # if so, execute `git status'
              git status
            else
              # else run `ls'
              ls -l
            fi
          fi
          # in any case run the `accept-line' widget
          zle .accept-line
        }
        # create a widget from `my-accept-line' with the same name
        zle -N accept-line my-accept-line
        # rebind Enter, usually this is `^M'
        bindkey '^M' accept-line
    

This replaces `enter` (empty command line), with either `ls` or `git status`
if in a git repository.

This beautifully works as expected, I never got any bug because of this (as
this could be expected for low level aliasing), and it does exactly what I'd
expect: get current status of the current folder.

Now typing `git status` elsewhere is such a pain!

~~~
m3at
Late on this as well but in case it's useful to you, I use this for quick "git
add":

    
    
      ga () {
              if test "$#" -eq 0
              then
                      echo "No arguments (0_0)?"
              elif test "$#" -eq 1
              then
                      git add -u && git commit -m "$(echo $1 | sed 's/^./\U&\E/')"
              else
                      git add ${@:1:$(( $# - 1 ))} && git commit -m "$(echo ${@:$#} | sed 's/^./\U&\E/')"
              fi
      }
    

Usage:

    
    
      # Add all modified files and capitalize the commit message
      ga "fix typo in README"
      # Add some files and treat last arg as commit message
      ga main.rs point.rs "speedup by 10e9"

------
zzo38computer
I have two programs that open Firefox. I also have some other programs, too.

fav

    
    
      #!/bin/bash --
      f0() {
        echo 'select moz_bookmarks.title || '"'"' = '"'"' || url from moz_places, moz_bookmarks on moz_places.id = moz_bookmarks.fk where parent = 2;' | sqlite3 /home/user/.mozilla/firefox/twht79zd.default/places.sqlite
      }
      f1() {
        firefox `echo 'select url from moz_places, moz_bookmarks on moz_places.id = moz_bookmarks.fk where moz_bookmarks.title = '"'$1'"';' | sqlite3 /home/user/.mozilla/firefox/twht79zd.default/places.sqlite`
      }
      f$# $1
    

wikipedia

    
    
      #!/bin/bash --
      firefox 'http://en.wikipedia.org/wiki/Special:Search?search='`node -p 'escape(process.argv[1])' "$1"`
    

(Maybe there is a better way than calling Node.js to escape the URL)

icanhazip

    
    
      #!/bin/bash --
      curl 'http://icanhazip.com/'
    

repeat

    
    
      #!/bin/bash --
      X=$1
      shift
      for X in `seq 1 $X`; do "$@"; done

~~~
vuln
ipinfo

    
    
      #!/bin/bash --
      curl 'http://ipinfo.io'
    

ipinfo is a lot more verbose. Depending on your needs...

Ex result: $curl ipinfo.io { "ip": "XXX.XXX.XXX.XXX", "hostname":
"XXX.XXX.XXX", "city": "XXX", "region": "XXX", "country": "US", "loc":
"XXX,XXX, "postal": "XXX", "phone": "XXX", "org": "ASXXX XXX XXX XXX" }

------
tbronchain
Some basic aliases I couldn't live without:

    
    
        alias rm='rm -i'
        alias mv='mv -i'
        alias cp='cp -v'
        alias ls='ls --color=auto -Fh'
        alias ll='ls -l'
        alias lla='ls -la'
        alias clean='rm -rfv *~ .*~ \#*\# .\#*\#'
        alias j='jobs'
        alias rm='rm -i'
        alias cp='cp -v'
        alias mv='mv -v'
    

Workspace management

    
    
        function workon () {
            LOC="$1"
            cd "${HOME}/work/$LOC"
            tmux attach -dt "$LOC" || tmux new -s "$LOC"
        }
    

Handle the git submodules nightmare (a little) more easily

    
    
        alias subupdate='git submodule init; git submodule sync; git submodule update --init --recursive;'
    

Colored prompt with git branch:

    
    
        PMT=" "; if [  $UID -eq 0 ];then PMT="# " ;else PMT="$ " ; fi
        WHITE="\[\033[0m\]"
        YELLOW="\[\033[0;33m\]"
        GREEN="\[\033[0;32;40m\]"
        BLUE="\[\033[1;34m\]"
        export PS1="[$GREEN\u@\h $BLUE\W$WHITE:$YELLOW\$(git branch 2>/dev/null | grep '^*' | colrm 1 2)$WHITE]"$PMT
    

Run a quick web server

    
    
        alias simpleWebServer='python -m http.server 8888'
    

If you are using tmux, WSL, and ssh all together, you may sometimes need
something like this (I always keep it in my bash_aliases and since never had
color issues :)

    
    
        if [ "$TERM" == "screen" ]; then
            export TERM="screen-256color"
        fi

------
mttyng
Some simple things, but little timesavers:

    
    
      function mk() {
        mkdir -p $1 && cd &1
      }
    
      alias gpm='git pull master'
      alias gcm='git checkout master'
      alias grh='git reset --hard HEAD'
      alias gs='git status'
      alias gd='git diff'
    
      alias h='history | grep' # Use like, "h ssh" to see all ssh in your history

------
gr4viton
Well the most used, and first thing i add when i get to a new system is:

    
    
       rcbash='~/.bashrc' 
       alias src="source $rcbash"
       alias vrc="vim $rcbash"
       alias vimo="vim -O"  # vsplit files
    
    

And then, a little snippet which made my "bashrc" less repetitive when it
comes to folder aliases.

    
    
       gr4_folderize() {
        # creates aliases and variables for a path
        #
        # $1 = used abbreviation
        # $2 = folder path
        #
        # gr4_folderize "esp32" "/srv/dd/esp32"
        # creates aliases `cdesp32`, `lsesp32` and `diresp32` env
    
        # ${param:?word} writes `word` to stdout when param is unset or null
        local abbrev="${1:?No abbreviation alias.}"
        local folder="${2:?No directory to folderize.}"
    
        export dir${abbrev}="$folder"
        which > /dev/null 2>&1 cd${abbrev} || alias cd${abbrev}="cd $folder"
        which > /dev/null 2>&1 ls${abbrev} || alias lll${abbrev}o="lla $folder"
       }

~~~
gr4viton
Plus `ask_yes` if you want to ask if user is sure.

    
    
       ask_yes () {
        read -r -p "$1 = Are you sure? [y/N] " response
        if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
        then
            return 0  # true = 0
        else
            return 1  # false = 1
        fi
       }
    

Plus `countdown timer` to make user think about what he has done, before he
does it. (Code is a mess cause i used some snippet then created another from
it)

    
    
      countdown_str () {
        # countdown "00:01:00" # = hh:mm:ss
        IFS=:
        set -- $*
        secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} ))
        while [ $secs -gt 0 ]
        do
          sleep 1 &
          printf "\r%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60))
          secs=$(( $secs - 1 ))
          wait
        done
        echo
      }
    
      countdown_5 () {
        countdown 5 2>/dev/null
      }
    
      countdown () {
        secs=${1:-"00"}
        mins=${2:-"00"}
        hours=${3:-"00"}
        chars=$(printf "%02d:%02d:%02d" $hours $mins $secs)
        echo "Countdown from $chars"
        countdown_str $chars 2>/dev/null
      }

------
0xferruccio
I have aliases with the name of every project that open up a productive
environment.

Eg. open a project with “Visual Studio Code” get latest version from git,
reset db and run seeding. Then install dependencies and run dev server, while
opening chrome at the right localhost address. I usually run the command walk
away to get a drink or food and when I’m back everything is running so I can
just start working!

------
btschaegg
I dislike pretty much the entire Windows command line, except for one small
bit of it: `start` (for the purpose of launching stuff in the background and
disowning it, not for the `xdg-open`-like functionality).

So, I had this in my rc files for a while:

    
    
      start() { nohup "$@" &> /dev/null &; }
    

After that, I replaced the function with the custom command from here:
[http://web.archive.org/web/20151221072546/https://felixmilea...](http://web.archive.org/web/20151221072546/https://felixmilea.com/2014/12/running-
bash-commands-background-properly/)

I'd still like to have auto completion for this, though, but I never got
around to learning about the ways to achieve that in bash and zsh.

Edit: Also, the one I probably use the most:

    
    
      alias l="ls -ltrash"
    

although I've started to replace it with

    
    
      e() { exa -bghHliSa --color=always "$@" | bat; }
      et() { exa -bghHliSTa --color=always "$@" | bat; }

------
xelxebar
I use bash, but really like the RPROMPT idea from zsh, so mimick that as best
as I can.

It turns out that bash has a PROMPT_COMMAND variable which gets called before
writing out PS1, so I use this to write my own rprompt. The main idea is just
to use tput to draw a thing on the right and restore the cursor position
afterward.

As is, I have something like below right-justified at each prompt:

    
    
        user@host:pwd (git-branch)
    

It even degrades nicely if horizontal space starts getting cramped. Actually,
the code is (I believe) just posix shell, so I define relevant functions in
.profile and have .bashrc and .mkshrc use them as appropriate. Since it's a
bit long, here are some pastebins that should be drop-in workable:

\- profile: [http://ix.io/1yiC/sh](http://ix.io/1yiC/sh)

\- bashrc: [http://ix.io/1yiA/bash](http://ix.io/1yiA/bash)

\- mkshrc: [http://ix.io/1yiB/ksh](http://ix.io/1yiB/ksh)

There are a couple caveats. Bash clears the whole line when deleting
characters, which causes the rprompt to be cleared as well. On the other hand,
mksh works as expected. Also, if you enter really long commands into the
prompt, they will eventually bump into and overwrite the rprompt, instead of
clearing it wholesale. I've not found this too much of a problem though.

In the code above, the rprompt() function defines the actual contents of the
prompt and performs the graceful degredation. The rprompt_draw() function does
the actual drawing and prompt_draw() links these two together to be used by
bash, mksh, etc.

Feel free to ask my any questions or hate on my code.

~~~
enriquto
I like to put useful information in the prompt, but yours looks too cluttered
for my liking. I particularly dislike the fact that most of the information of
your prompt is nearly constant, thus very redundant. Putting the CWD inside
the prompt is useless. You can just run pwd yourself if you are lost, but most
of the time you already know where you are. Similarly for the username and the
hostname. If you only deal with two or three servers, you can color code your
prompt symbol to those, and obtain a much shorter and cuter prompt.

Useful information that is still _not_ in your prompt:

\- status of the last run command: $?

\- number of jobs in the background, if any

I have this, with some colors thrown in:

    
    
        PS1='$(if [ \j != "0" ] ; then echo "[\j]"; fi)$?\$ '

~~~
xelxebar
That's all quite easy to change in the rprompt() function. I tried hard to
factor everything out, so the prompt content specification itself is clear and
obvious.

Basically, for the reasons you mention, I dislike having that info set in PS1,
but I find it considerably less distracting when right-justified. Having it
visible, though, makes it easy to ascertain the execution context of commands
in the terminal history buffer.

The status of last run command I have on my PS1. If it exits 0, then it's just
a simple

    
    
        $
    

otherwise, it's:

    
    
        errno$
    

I do like your idea of showing current background jobs, but I find myself
relying more on tmux windows than background jobs, so I suspect that number
would be mostly constant for myself anyway.

~~~
enriquto
> I do like your idea of showing current background jobs, but I find myself
> relying more on tmux windows than background jobs, so I suspect that number
> would be mostly constant for myself anyway.

Sure! the idea is that background jobs are very rare, and their existence
should be clearly indicated in the prompt (in bright red). Usually, there are
zero jobs and the prompt is silent about that.

------
mflower
These are probably the 3 I find most useful:

Copies the directory of the current git dir into the clipboard.

    
    
        which pbcopy &> /dev/null
        if [[ $? -eq 0 ]]; then
            CLIPBOARD_COMMAND="pbcopy"
        fi
        which clip &> /dev/null
        if [[ $? -eq 0 ]]; then
            CLIPBOARD_COMMAND="clip"
        fi
    
        cpgitdir() {
            GIT_DIR=`git remote show -n origin | grep "Fetch URL" | sed -e "s/  Fetch URL: //"  | tr -d '\n'`
            echo "Copying git dir to clipboard: $GIT_DIR"
            echo $GIT_DIR | tr -d '\n' | $CLIPBOARD_COMMAND
        }
    

Allows you to split your .bash_profile into multiple .bash_profile files for
clarity

    
    
        if [[ -d ~/.bash_profile.d ]]; then
            for file in `find ~/.bash_profile.d -type f`; do
                source $file
            done
        fi
    

Simple calculator

    
    
        calc () {
            bc -l <<< "$@"
        }

------
yboris
Before I check in my code I check whether I've made any silly mistakes /
forgot to remove console.log, etc.

    
    
        alias diff='diff2html -s side'
    

This requires the diff2html cli -
[https://diff2html.xyz/](https://diff2html.xyz/) \- install with `npm install
-g diff2html-cli`

------
BigBalli
Love this thread! Some of mine (excluding similar to what has already been
mentioned):

    
    
      alias cleangopro="rm -rf /Volumes/GOPRO/DCIM/*"
      alias mkdir="mkdir -pv"
      alias ssh<proj>="ssh <user>@<ip>"
      alias clearmail='sudo rm /var/mail/<user>'
      alias flushcache='dscacheutil -flushcache && sudo killall -HUP mDNSResponder'
      alias listenforpwd="sudo tcpdump port http or port ftp or port smtp or port imap or port pop3 or port telnet -lA | egrep -i -B5 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd=|password=|pass:|user:|username:|password:|login:|pass |user '"
      alias listenforuseragent="sudo tcpdump -vvAls0 | grep 'User-Agent:'"
      alias listenforgetreq="sudo tcpdump -vvAls0 | grep 'GET'"

~~~
remram
SSH has a configuration file (.ssh/config) which lets you set configuration
for specific hosts and even aliases:

    
    
        Host reproserver
        User remi
        Hostname 128.122.217.96
        IdentityFile ~/.ssh/id_rpz

------
loganekz
One I have been using for over 20 years, aliasing l to my favorite ls
switches:

    
    
        alias l='ls -GFla'

~~~
20190115
Ditto. (Though not 20 years).

I use these 3

    
    
       alias ls='ls --color=auto --group-directories-first'  # override
       alias l='ls -hF'
       alias ll='ls -hAlF'
       alias lt='ls -clthF'
    

Also, incredibly useful:

    
    
       alias c='clear'
    

I type `l` and `c` all the time. Then I get on a different machine and
`command not found`.

------
eterps

      mcd(){ mkdir "$1"; cd "$1"; }
      alias vd='vim -d' # vimdiff
      alias grep=egrep

------
ma1f
# z for quickly switching between commonly used dirs eg. `z ex` -> cd
/mnt/c/dev/api.extensions

    
    
      # https://github.com/rupa/z
      source ~/z.sh
    

git helpers

    
    
      # update all git repos in subdirs
      alias gitp="ls -d */ | xargs -P10 -I{} git -C {} pull"
      # fetch updates for git repos in subdirs
      alias gitf="ls -d */ | xargs -P10 -I{} git -C {} fetch --all"
    

selection of most commonly used git aliases

    
    
      ci = commit -m
      cf = clean -fxd
      cl = clone
      co = checkout
      cm = commit --amend --no-edit
      lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %Cblue<%an>%Creset' --abbrev-commit --date=relative --all -n 25
      pf = push -f --follow-tags
      rb = rebase master
      st = status -sb

------
twhitbeck
Use docker to run binaries without installing:

    
    
      alias·mongo='docker·run·-it·--rm·--network=host·mongo·mongo'
      alias·aws='docker·run·-it·--rm·-e·AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID·-e·AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY·--network=host·mesosphere/aws-cli'

------
chris_mc
I have an alias for cd which prints any file called '.cd-reminder' in a
directory. I make notes like "pull and rebase daily!" in my work repos. I'll
post it later from my laptop. It's just an if statement in a function, though,
so not hard to reproduce yourself.

------
W0lf
I have a whole repository also including several dotfiles that I maintain for
already several years [1]. Following are some snippets from the
dotfiles/.alias and dotfiles/.functions files from that repository that
probably are the most interesting and which I am using on a regular basis:

    
    
        # easier navigation
        alias ..="cd .."
        alias ...="cd ../.."
        alias ....="cd ../../.."
        alias .....="cd ../../../.."
        alias ~="cd ~"
    
        # Get current public ip address
        alias ip="dig +short myip.opendns.com @resolver1.opendns.com"
    
        # Alias for summing a column
        alias mksum="paste -sd+ - | bc"
    
        # Export pbcopy / pbpaste to linux 
        if [[ "${OSTYPE}" == "linux"* ]]; then
            alias pbcopy="xclip -selection clipboard"
            alias pbpaste="xclip -selection clipboard -o"
        fi
    
        # create a new directory and enter it
        function mkd() {
            mkdir -p "$@" && cd "$_";
        }
    
        # plot stuff directly from the command line.
        # Example: seq 100 | sed 's/.*/s(&)/' | bc -l | plot linecolor 2
        # -> Generate 100 numbers, wrap it in s(<num>) and calc sin(<num>)
        function plot() {
            { echo 'plot "-"' "$@"; cat; } | gnuplot -persist;
        }
    
        # wrapper for easy extraction of compressed files
        function extract () {
          if [ -f $1 ] ; then
              case $1 in
                  *.tar.xz)    tar xvJf $1    ;;
                  *.tar.bz2)   tar xvjf $1    ;;
                  *.tar.gz)    tar xvzf $1    ;;
                  *.bz2)       bunzip2 $1     ;;
                  *.rar)       unrar e $1     ;;
                  *.gz)        gunzip $1      ;;
                  *.tar)       tar xvf $1     ;;
                  *.tbz2)      tar xvjf $1    ;;
                  *.tgz)       tar xvzf $1    ;;
                  *.apk)       unzip $1       ;;
                  *.epub)      unzip $1       ;;
                  *.xpi)       unzip $1       ;;
                  *.zip)       unzip $1       ;;
                  *.war)       unzip $1       ;;
                  *.jar)       unzip $1       ;;
                  *.Z)         uncompress $1  ;;
                  *.7z)        7z x $1        ;;
                  *)           echo "don't know how to extract '$1'..." ;;
              esac
          else
              echo "'$1' is not a valid file!"
          fi
        }
    

[1] [https://github.com/NewProggie/Dev-
Utils](https://github.com/NewProggie/Dev-Utils)

~~~
callahad
You might enjoy replacing your extract function with atool
([https://www.nongnu.org/atool/](https://www.nongnu.org/atool/)) which
provides aunpack. It works similarly, but has niceties like creating and
unpacking into a subdirectory to avoid accidentally spraying files all over
the current working directory if the archive has multiple files at its root.

~~~
sjf
Similarly, the unp script automatically detects and unpacks most archives
[https://manpages.debian.org/jessie/unp/unp.1.en.html](https://manpages.debian.org/jessie/unp/unp.1.en.html)

------
VelNZ

      alias ll='ls -l'

~~~
Tharkun
"alias ll='ls -al'" is the first thing I type every time I ssh into any system
that isn't mine.

------
mrmattyboy
Used to work primary using docker on my laptop, but been working on some
bigger applications that need to be run on beafier machines, so just set
environment variable and have these:

    
    
        $ cat ~/bin/docker
        #!/bin/bash
        
        if [ "$DOCKER_HOST" != "" ]
        then
          HOST_ARG="-H $DOCKER_HOST"
        fi
        
        /usr/bin/docker $HOST_ARG $@
    
        $ cat ~/bin/docker-compose
        #!/bin/bash
        
        if [ "$DOCKER_HOST" != "" ]
        then
          HOST_ARG="-H $DOCKER_HOST"
        fi
        
        /usr/local/bin/docker-compose $HOST_ARG $@

------
xelxebar
Strictly speaking, tmux is out of scope of the question, but I hope some
people would be interested.

I found myself needing to use deeply nested tmux sessions a few times and
navigating between nestings is a huge pain under a vanilla setup. Using some
configuration trickery, I was able to hack in keys to "focus" between nesting
levels. Here's a repo I have it sitting under:

[https://github.com/xelxebar/tmux-
addons/tree/master/nesting](https://github.com/xelxebar/tmux-
addons/tree/master/nesting)

The code should be relatively drop-in and the README not terrible.

I'd love to hear thoughts.

------
rcdwealth
Quickly find messages in your local Maildirs. Full replacement for Google mail
and other centralized spying email systems. It uses
[https://github.com/djcb/mu](https://github.com/djcb/mu) and mutt
[https://www.mutt.org](https://www.mutt.org) in ~/.bash_functions directly
from shell, and displays emails

    
    
      function search-messages () {
         /usr/local/bin/mu find --clearlinks --format=links --linksdir=~/Maildir/search "$@" && mutt -f ~/Maildir/search
     }

------
DyslexicAtheist

      function certchain() {
          # Usage: certchain
          # Display PKI chain-of-trust for a given domain
          # GistID: https://gist.github.com/joshenders/cda916797665de69ebcd
          if [[ "$#" -ne 1 ]]; then
              echo "Usage: ${FUNCNAME} <ip|domain[:port]>"
              return 1
          fi
    
          local host_port="$1"
    
          if [[ "$1" != *:* ]]; then
              local host_port="${1}:443"
          fi
    
          openssl s_client -connect "${host_port}" </dev/null 2>/dev/null | grep -E '\ (s|i):'
      }

~~~
joshenders
I’m flattered

~~~
DyslexicAtheist
haha, this made my day! small world :)

------
tcbawo
I use 'u' to navigate up parent directories:

    
    
      alias u="cd .."
      alias uu="cd ../.."
      alias uuu="cd ../../.."
      alias uuuu="cd ../../../.."

~~~
bussierem
I found a much better way of handling this via SO one time, and I've kept it
ever since:

    
    
      # Up command, from stackoverflow.  Takes optional number of 
      levels to cd ../
      up(){
        local d=""
        limit=$1
        for ((i=1 ; i <= limit ; i++))
          do
            d=$d/..
          done
        d=$(echo $d | sed 's/^\///')
        if [ -z "$d" ]; then
          d=..
        fi
        cd $d
      }

------
solarized

      alias ea='vim ~/.bash_aliases'
      alias ear='source ~/.bashrc'
    

* i type 'ea' whenever i think a commands should aliased.

* add new aliases

* exit dan type 'ear' to refresh the bashrc.

go for another productive terminale.

~~~
scns
alias als="vi ~/.bash_aliases && . ~/.bash_aliases"

------
adontz
To fix some bugs

    
    
        shopt -s checkwinsize
        shopt -s autocd
    
    

To make life better to my taste

    
    
        alias tmux="tmux new -A -s root"
        export HISTCONTROL=ignoredups
    
    

To distinguish between development, test and production environments by color
(VERY userful)

    
    
        export PS1='[\[\e[1;91m\]\u\[\e[0m\]@\[\e[1;31m\]\H\[\e[0m\] \[\e[1;95m\]\w\[\e[0m\]]\\$ '
        export PS1='[\[\e[1;92m\]\u\[\e[0m\]@\[\e[1;32m\]\H\[\e[0m\] \[\e[1;95m\]\w\[\e[0m\]]\\$ '
        export PS1='[\[\e[1;93m\]\u\[\e[0m\]@\[\e[1;33m\]\H\[\e[0m\] \[\e[1;95m\]\w\[\e[0m\]]\\$ '

------
nicwolff
in .gitconfig:

    
    
      recent = for-each-ref --count=25 --sort=-committerdate refs/heads/ --format="%(refname:short)"
    

so `git recent` lists the last 25 branches, and then in .bashrc:

    
    
      alias co='select br in $(git recent); do git co $br; break; done'
      alias coo='select br in $(git br -r|grep -v "("|grep -v HEAD|cut -c3-|sed "s/^origin.//"); do git co $br; break; done'
    

and now `co` gives me a menu of recent local branches to check out, and `coo`
does the same for remotes on origin

------
panta
Some of mine not already seen:

    
    
        alias mirror='wget -m -r -np -p -k -E'
        alias g_short_hash='git rev-parse --short --verify HEAD'
        alias g_head_branch='echo "`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`"'
        alias g_branch_w_hash='echo "`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`-`git log --pretty=format:\"%h\" -1`"'
    

On OS X:

    
    
        alias sleepnow="pmset sleepnow"
        alias netstat_tanp="lsof -Pnl +M -i4 -i6"

------
uby2
Some of aliases in my bash profile

#Git Aliases alias gc="git checkout" alias gp="git pull" alias gp="git pull
--rebase" alias gb="git branch" alias gs="git status" alias gd="git diff"
alias gl="git log --oneline" alias gu="git ls-files --others --exclude-
standard"

#HDFS Alias alias hls="hdfs dfs -ls" alias hcat="hdfs dfs -cat" alias
hrm="hdfs dfs -rm" alias hrmf="hdfs dfs -rm -r -f" alias hmd="hdfs dfs -mkdir"

~~~
lawry
I also have aliases for git, only I noticed gs starts Ghostscript on places
where I don't have these set, so I changed all my git aliases to gg:

    
    
      ggs -> git status
      ggco -> git checkout
      ggd -> git diff
      ggap -> git add --patch

------
rcdwealth
Convert any video to webm with specified bitrate:

    
    
      $ video2webm 300k myvideo.mp4 othervideo.mpg third.mov
    
      function video2webm () {
         bitrate=$1;
         shift;
         for file in "$@";
         do out=${file%.*}.webm;
            ffmpeg -y -i "$file" -c:v libvpx-vp9 -b:v $bitrate -pass 1 -speed 4 -c:a libopus -f webm /dev/null && \
                ffmpeg -i "$file" -c:v libvpx-vp9 -b:v $bitrate -pass 2 -speed 1 -c:a libopus "$out";
         done;
     }

------
bhaak
My git related aliases:

    
    
      alias master='git checkout master'
      alias f='git fetch --all'
      alias s='git status --untracked-files=all'
      # go to the last branch I worked on, excluding master and the current branch
      alias lb='git checkout `git for-each-ref --sort=-committerdate refs/heads/ | grep -v refs/heads/master$ | grep -v \`git rev-parse --abbrev-ref HEAD\`| head -n1 | cut -d \/ -f 3-`'

------
Tharkun
I have a bunch of project/location specific environment preparing handles in
my .aliases file.

Stuff like:

alias @projectName="cd $project && alias java='/some/specific/version' &&
export SOME_VAR=value"

or

alias @untrustedWifi="tor && torbrowser && set up an SSH tunnel to access mail
etc"

I can't really share the actual contents, because they depend on a boatload of
scripts in my ~/bin dir and they're all pretty specific to my environment.

~~~
renox
I do this plus set the prompt accordingly to remind me in which state it is

------
zorked
alias grpe=grep

Nothing comes close to the amount of time I saved with this one.

~~~
yesenadam
Hehe I liked the 'lcoate' one on this page too, same idea. It might be super-
useful to have a function that, if command not found and if there's an anagram
of what you typed that _is_ a command, asks if you meant that instead, y/n?
(That would make computers seem a lot more intelligent!)

~~~
benterris
You might be looking for this:
[https://github.com/nvbn/thefuck/blob/master/README.md](https://github.com/nvbn/thefuck/blob/master/README.md)

~~~
yesenadam
Thanks, but my computer's too old to read that page. It's a thing already?

~~~
benterris
Yes, it's a command you can use when the previous one failed for some reason,
that tries to correct the typos if any, or adds sudo or a missing option...

------
binaryapparatus

        function convert-decimaltobinary(){
            n="$1"
            bit=""
            while [ "$n" -gt 0 ]; do
                bit="$(( n&1 ))$bit";
                : $(( n >>= 1 ))
            done
            printf "%s\n" "$bit"
        }
        function convert-binarytodecimal(){
            echo "$((2#$1))"
        }
        function convert-hextodecimal(){
            echo $(( 16#$1 ))
        }

~~~
yesenadam
I think I'll use them more if they're cdb, cbd, chd. Thanks!

------
franky47
Zsh function to create a directory and cd into it in one go:

    
    
      function mkcd() { mkdir -p "$@" && eval cd "\"\$$#\""; }

~~~
I_complete_me
zsh already has the take command for this AFAIK

------
chewxy
I work on a number of Go projects. This is one that lasted me for close to a
decade now:

    
    
        function workspace_cd() {
            cd $@ && [ -f ".bashworkspace" ] && source .bashworkspace
        }
        alias wscd="workspace_cd"
    

Each .bashworkspace file contains something like this:

    
    
        export GOPATH={PATH HERE}
        export PATH=$GOPATH/bin:$PATH
        export GHC_PACKAGE_PATH={PATH HERE}

------
catcar

      unameOut="$(uname -a)"
    
      case "${unameOut}" in
    
    	*Microsoft*) machine="WSL";;
    
    	Linux*)      machine=Linux;;
    
    	Darwin*)     machine=Mac;;
    
    	CYGWIN*)     machine=Cygwin;;
    
    	MINGW*)      machine=MinGw;;
    
    	*)           machine="UNKNOWN:${unameOut}"
    
      esac
    
      unset unameOut
    
      PROMPT_COMMAND='echo -ne "\033]0;[${machine}] ${USER}@${HOSTNAME}: ${PWD}\007"'

------
l0b0
Folder Git[0], a quick hack to for example pull all my 100+ repos in one go.
First version eight years ago, and I still use it every day.

[0] [https://gitlab.com/victor-
engmark/fgit/blob/9575803b3bf277d5...](https://gitlab.com/victor-
engmark/fgit/blob/9575803b3bf277d5b16a5ee4723330f088628bf0/fgit.sh)

~~~
explainplease
[https://myrepos.branchable.com/](https://myrepos.branchable.com/)

------
sepent
I never use vim or emacs viper-mode on my machine. But I let other people to
use my emacs viper-mode:

    
    
      vi()
      {
          emacs -nw --eval '(and (switch-to-buffer "foobar") (setq viper-mode t) (setq viper-inhibit-startup-message t) (setq viper-expert-level 1) (viper-mode))' "$@"
      }
    
      alias vim=vi
      alias vim.tiny=vi
      alias vim.basic=vi

------
objectiveariel
In my bash_profile is a simple echo which makes the shell say hi to me every
time I open an instance. Brightens my day a little bit:

    
    
      echo 'Hello dude '
    

As an iOS dev, this one is super useful:

    
    
      alias cdd='rm -rf ~/Library/Developer/Xcode/DerivedData/* && echo "Cleared DerivedData/"'

~~~
sleepychu
cdd seems like a bananas alias for something that does an rm -rf!

Have you ever done it by mistake?

~~~
saagarjha
It doesn't really matter; the directory is Xcode's auto-generated build
products and can be recreated quite easily.

------
rcdwealth
Cannot remember pacman queries:

    
    
      # Pacman functions
       function pacinstall () {
         sudo pacman -S "$@"
      }
     
       function pacremove () {
         sudo pacman -R "$@"
      }
     
       function paclist () {
         sudo pacman -Ql "$1" | less
      }
     
       function pacsearch () {
         sudo /usr/bin/pacsearch "$@" | less
      }

------
amirexdev
These are my favorites:

alias ia="open $1 -a /Applications/iA\ Writer\ Classic.app"

alias makepass="pwgen -s 30 | awk '{print $NF}' | pbcopy"

alias phplint="find . -name \" _.php\ " -print0 | xargs -0 -n1 -P8 php -l"

alias quicklint="find . -name \"_.php\" -depth 1 -print0 | xargs -0 -n1 -P8
php -l"

alias loc="find . -name '*.php' | xargs wc -l"

------
amanzi
One useful alias I have not seen mentioned here is this:

    
    
      alias myip='curl -s https://api.ipify.org'
    

Just prints out my current public IP address. I also have a bunch of others
mentioned in this thread, and I've abbreviated a bunch of self-explanatory
docker-compose commands, e.g. dcdown, dcup, dcrestart, dcpullup, etc

~~~
eterps

      curl ifconfig.me
    

is also easy to remember

------
shashwat986
I've used these so much:

    
    
        function gc() { grep -rnI "$@" * ;}
        function gcA() { grep -rnI -A 5 "$@" * ;}
        function gcB() { grep -rnI -B 5 "$@" * ;}
        function gcC() { grep -rnI -C 5 "$@" * ;}
        function gcf() { grep -rnIl "$@" * ;}
    

Just helper functions built on top of grep

~~~
yesenadam
And what do they do? It's not obvious.

edit: Thank you both!

~~~
jmts
-r enables recursion

-n enables line numbers

-I (eye) ignores matches on binary files

-l (ell) lists the filenames of matching files only (overrides -n)

-A, -B, and -C specify how many lines of context after, before, or around the match to display.

"$@" adds any additional command line arguments passed to the functions.

* selects all the files and directories in the current directory.

So, without other arguments, the first four functions list matches with line
numbers for all files (ignoring binary files) in the current directory and
below, with 0 lines context (match only), 5 lines context after, 5 lines
context before, and 5 lines context around the match respectively. The final
function lists the filenames only and provides no context or line numbers.

------
bckmn
I use my git aliases dozens of times each day, especially the last few that
pop open relevant repository webpages:
[https://github.com/andjosh/dotfiles/blob/master/.gitconfig#L...](https://github.com/andjosh/dotfiles/blob/master/.gitconfig#L37)

------
dryule

      alias c='cd'
      alias cd='cd ..'
    

Yes, I am lazy. Yes it has saved me thousands of keystrokes

------
lclarkmichalek
My diary:

    
    
        alias today='vim ~/notes/$(TS="Europe/London" date +%Y-%m-%d).txt'

------
Dowwie
One of my most valuable aliases used is for backing up deleted files and
directories using the trash-cli Linux utility.

The trash-cli utility has some quirks related to mounted drives but once you
understand how to set up correctly, aliasing rm to trash can save you from
losing files you've deleted by mistake.

------
pjc50
Not bash but git aliases, as a consequence of our gerrit workflow:

    
    
        alias.gerritpush=push origin HEAD:refs/for/develop
        alias.fixlast=!git commit -a --fixup=HEAD && GIT_EDITOR=true git rebase -i --autosquash HEAD~2
        alias.loglast=log -n 1 -p

------
rwmj

        export MAKEFLAGS=-j`nproc`
    

make will automatically parallelize builds for the number of cores on the
machine. It also breaks various things interestingly, particularly build
systems which don't pay attention to correct dependences.

------
rcdwealth
in .bash_functions with PostgreSQL

    
    
      $ age NAME YYYY-MM-DD
    

to get the age of anybody:

    
    
      function age () {
         NAME="$1";
         DATE="$2";
         if [[ $1 && $2 ]]; then
             AGE=$(psql -Stc "SELECT age(date('${DATE}'));");
             echo $NAME: $AGE, was born on $DATE | sed 's/ mon / month /' | sed 's/ mons \| mons,/ months /';
         else
             echo "No name or date supplied";
         fi
      }
    
      function child () {
         age "My child" "2012-03-12";
      }

------
ivdivd0
Simple aliases for find and grep, that allow to just look for something
without worrying about case sensitivity, escaping, etc.

    
    
      function ff {
          find . -iname \*$1\*
      }
    
      alias gr='ack -i'

------
nailer
If you've made the move to powershell:

[https://github.com/mikemaccana/powershell-
profile/](https://github.com/mikemaccana/powershell-profile/)

------
wolfwoolford
Directory specific history... Probably my most useful profile addition.

[https://github.com/wolfwoolford/dish](https://github.com/wolfwoolford/dish)

------
virtuabhi
alias vim='emacs'

------
packetpirate
It's not useful in any way, but I have one alias... "doot". It runs a Python
script that draws a skeleton playing the trombone over an 80s scrolling grid
and sunset.

------
emmelaich
Because I want to do file completion on files with datetimes (think colons)

    
    
       COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
    

See the Bash FAQ for more info.

------
jonasmst
For pretty-printing tabular data (tab- and comma-separated):

alias seetsv="column -s $'\t' -t"

alias seecsv="column -s ',' -t"

------
michael_leachim
I use prefix qq for my commands because:

    
    
      1. It is easy to discover all customizations 
         via autocomplete
      2. It is not going to clash 
         with existing functionality
    
      # (Sort stuff by size, latest down, in a directory)
      alias qqsize="ls -lSrh"
      alias qqdate="ls -lrt"
      
      # First 100 of largest files/directories in a folder
      function qqlargest_files_100(){
        du -a ./ | sort -n -r | head -n 100
      }
      
      # Archivate item 
      qq-tar-gz-it () {
        tar -zcvf  $2 $1;
      }
      
      # Convert video to a gif
      function qq_convert_video_to_gif(){
        ffmpeg -i $1 $1.gif  
      }
      
      # Push to GitHub
      
      function togithub__master(){
          git add -A;
          git commit -m $1;
          git push github master;
      }
      
      # Symlink config file
      # 1. Move dotfile to a config directory.
      # 2. Strip the dot
      # 3. Symlink that file back to its place
      function qqsymlink_config_file(){
          directory_for_dot_file=$2
          name_of_dot_file=$1
          basename_of_dotfile=$(basename $name_of_dot_file)
          echo "Basename of dotfile: $basename_of_dotfile"
          dot_file_with_striped_dot=${basename_of_dotfile:1}
          new_file_path=$directory_for_dot_file/$dot_file_with_striped_dot
          echo "Moving $name_of_dot_file to $new_file_path";
          mv $name_of_dot_file $new_file_path;
          echo "Symlinking file $new_file_path to $name_of_dot_file ";
          ln -s $new_file_path  $name_of_dot_file;
      }
      
      # Enable touchpad
      function qq__touchpad_enable(){
          xinput set-prop $(xinput | grep Touch | grep -Po 'id=\K[0-9]+')  "Device Enabled" 1
      }
      
      # Set monitor highlighting 
      alias qq_set_higlighting_to_level_1_100="sudo xbacklight -set"
      
      # Display wifi SSID's
      alias qqwifi-spots="sudo iwlist scan | grep ESSID"
      
      # Add wifi network 
      function qqadd-wifi-network(){
          ## add-wifi-network just_wifi mypassword
          wpa_passphrase $1 $2 >> /etc/wpa_supplicant/wpa_supplicant.conf
      }
      
      # Various, misc
      
      # Mirror (webcam)
      alias mirror="vlc v4l2:///dev/video0"
      
      # Stopwatch/countdown
      function stopwatch(){
        date1=`date +%s`; 
         while true; do 
          echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r"; 
          sleep 0.1
         done
      }
      
      function countdown(){
         date1=$((`date +%s` + $1)); 
         while [ "$date1" -ge `date +%s` ]; do 
           echo -ne "$(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r";
           sleep 0.1
         done
      }
      
    

Some other stuff that I use daily and is too long to list here is:

    
    
      * an increment, deduplicating backup that takes
        around $0.52 per month on BackBlaze and on the 
        external hard drive via one command. 
        (Shameless plug: https://github.com/MichaelLeachim/borg_backblaze_backup)
      * Internet blocker.  (https://github.com/MichaelLeachim/internet_block)
    
    

Edit, formatting.

~~~
aptmiguk
Cool, I like the qq-tar-gz-it, but I changed it to this:

function qq-tar-gz-it () { tar -zcvf ${1}.tar.gz $1; }

Saves a step.

------
triebefx
use parallel compression/decompression

    
    
      alias bzip2='pbzip2'
      alias bunzip2='pbzip2 -d'
      alias gzip='pigz'
      alias gunzip='pigz -d'
      alias xz='pixz'
      alias tar='tar --use-compress-program=pbzip2'
      alias tar='tar --use-compress-program=pigz'

------
rollopack
Determine external IP address alias ipget='dig +short myip.opendns.com
@resolver1.opendns.com'

------
fabianriosarias
#simple and saves me a lot of time

gpush(){ git add --all . && git commit -m $1 && git push origin $2 }

------
enriquto

        alias o=xdg-open
        alias dus='du -sh * | sort -h'
        alias mkae=make

~~~
gr4viton
for the `mkae` you should really use `thefuck` cli anti-typo tool ;)
[https://github.com/nvbn/thefuck](https://github.com/nvbn/thefuck)

------
Httqm
Workaround the excessively short TMOUT value with (without disabling it,
though) :

exec env TMOUT=259200 bash

------
Anon_troll

      # Linux hard mode
      set -e
    

The tab completion integration is especially nice.

------
roadst4r
add autocomplete for hosts found in known_hosts file

    
    
        complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" s

------
narze
Git add by hunks (not whole file)

    
    
      alias gap='git add -p'

------
thosakwe
“cdp” - Runs mkdir -p, followed by cd. Saves me thousands of keystrokes.

------
narze
Reload the shell itself

    
    
      alias reload='exec $SHELL -l'

------
egberts1
chezmoi

Because it is important to centralize all your dotfiles.

Disclaimer: I’m a chezmoi user.

[https://github.com/twpayne/chezmoi](https://github.com/twpayne/chezmoi)

------
delf123
alias gitl='git log --pretty=format:"%Cred%h %Cgreen %cd %Cblue%<(14,trunc)%an
%Creset %s %Cred %d %Creset" \--graph --date=short -20'

~~~
atonse
wow that's so damn useful. stealing.

------
vkaku
I alias cd to pushd

------
Waterluvian
git open

[https://github.com/paulirish/git-open](https://github.com/paulirish/git-open)

------
pizza

        alias v="nvim"

------
ratsimihah
alias emacs='emacs -nw'

Speaking of, what's this vi thing people keep mentioning? :>

------
the_jeremy

        #~/.inputrc is for nerds who don't want 1000-line bashrcs
        #C-w deletes previous word (by spaces) by default
        #bind C-q to delete previous word-segment instead of "start(?) term output"
        stty -ixon
        bind '"\C-q": backward-kill-word'
        #bind C-s to move cursor to previous [:space:] instead of "stop(?) term output"
        bind -r '\C-s'
        bind '"\C-s": shell-backward-word'
        #bind C-d to go forword, not crush the shell
        set -o ignoreeof
        bind '"\C-d": shell-forward-word'
        #miscellaneous useful inputrc binds
        #bind shift-tab to 'see how the next autocomplete option would look on the cmd line'
        bind '"\e[Z": menu-complete'
        #don't make me hit tab twice to see multiple completion options
        bind "set show-all-if-ambiguous on"
        bind "set show-all-if-unmodified on"
        #multi-complete shows filetypes by colors
        bind "set colored-stats on"
        #ellipsis at 3+ common characters with multi-complete
        bind "set completion-prefix-display-length 3"
        if [[ "$__os" == "mac" ]]; then
            #tab complete is no longer case-sensitive? interesting...
            bind "set completion-ignore-case on"
            #tab complete is not -_ sensitive.
            bind "set completion-map-case on"
        fi
        #vim mode is actually a super pain compared to emacs on the command line.
        set -o emacs
        #C-n/p now do double duty, so this is like the best of all 3 worlds? I'll take it
        bind '"\C-p":history-search-backward'
        bind '"\C-n":history-search-forward'
        
    
        #makes aliases work with sudo
        alias sudo='sudo '
        #use sudo -i to become root and keep your bashrc & vimrc
        alias -- -i='-E bash --rcfile $HOME/.bashrc'
        #can't get it to work when becoming other users. sucks to suck.
        alias apt-get='sudo apt-get'
        alias systemctl='sudo systemctl'
        alias sc='sudo systemctl'
        alias scr='sudo systemctl restart'
        alias firewall='sudo firewall-cmd'
        alias fw='sudo firewall-cmd'
        alias yum='sudo yum'
        alias yumy='sudo yum install -y'
        alias py='python'
        # b/c sed needs i with an empty string on Mac to properly in-place
        alias sd='sed -i"" -e'
        #alias ugh = sudo !!
        alias ugh='sudo $(history -p !!)'
        # -a: dotfiles. -I: not those dotfiles. -C: color.
        alias tree='tree -a -C -I ".git"'
        #tries to force color: (G):BSD; (--color):GNU, adds / after dirs, * after execs, etc (F);
        #and human readable sizes (h)
        alias ls='ls --color -GFh'
        alias la='ls --color -GFhla'
        alias cd.='cd ../'
        alias cd..='cd ../../'
        alias cd...='cd ../../../'
        alias cd....='cd ../../../../'
        #is it running? sometimes you need all the args (i.e., for java processes) to fully grep
        psg() {
            ps -ef | grep -i $* | grep -v grep || \
            ps -efwww | grep -i $* | grep -v grep
        }
        alias g.='grep '\''.'\'' -IrnHe'
        alias f.='find . -name'

~~~
axelrosen
I'll just add two more systemctl aliases I got

    
    
      alias scs='systemctl status'
      alias jc='journalctl --unit'

------
erroneousboat
alias gti="git"

------
TaelBE
alias please='sudo $(history -p !!)'

------
somanyquestions
gc="git commit -m"

------
geoelectric
I use these functions a lot: down and up. They're quite useful for navigating
big source trees where stuff isn't well laid-out but you don't remember exact
paths.

They work kind of like z/j, but you don't have to have been there before and
it will constrain to the current tree.

down SUB1 SUB2[...] does a _breadth-first_ search down-tree from your current
location, and takes you to the first directory with all the given substrings
in order in its path.

This differs from just wrapping basic find . -ipath, which does depth-first.
That way, down libs lands you in ./src/libs instead of
./src/a_subcomponent/foo/bar/libs.

up SUB1 does the same, but moves you up the tree instead. I didn't do multiple
substrings here because I never needed them--I mostly use them with down to
anchor to a subtree (e.g., down a_sub libs if I wanted the above result).

Both are case-insensitive as written. Change ipath to path in down and grep
-oi to grep -o in up to make them case sensitive instead.

They may or may not be symlink safe, and may or may not be spaces-in-paths
safe. Neither is in play in my source bases.

Last note, these were originally written in fish (ask me for those versions if
you want them) before I ported them to bash, so may not be examples of
stunning bash code. They've been tested on bash 3.2 (Mac), 4.x, and 5.0.

    
    
      function joinstr {
          local IFS="$1"
          shift;
          echo "$*"
      }
      
      function down {
          if [ -z "$1" ]; then
              echo "Usage: down SUBSTR [SUBSTR...]"
              return 1
          fi
      
          # foo bar baz becomes *foo*bar*baz*
          local pathspec=( "$@" )
          pathspec="*"$(joinstr "*" ${pathspec[@]})"*"
    
          local depth=1
          local dest=""
      
          # iterative depth first traversal to simulate breadth-first
          while true; do
              # Anything at all at this depth?
              local first_result=$(find . -mindepth "${depth}" -maxdepth "${depth}" -type d -print -quit)
              if [ -z "${first_result}" ]; then
                  # nope, we're done
                  break
              fi
      
              # How about what we're looking for?
              dest=$(find . -mindepth "${depth}" -maxdepth "${depth}" -ipath "${pathspec}" -type d -print -quit)
              if [ -n "${dest}" ]; then
                  # found it!
                  break
              fi
    
              depth=$((${depth} + 1))
          done
      
          if [ -z "${dest}" ]; then
              echo "down: could not find path matching ${pathspec}"
              return 2
          fi
      
          echo "down: changing directory to ${dest}"
          cd "${dest}"
      }
      
      function up {
          if [ -z "$1" -o -n "$2" ]; then
              echo "Usage: up SUBSTR"
              return 1
          fi
      
          # look for substr starting at parent
          local dest=$(echo ${PWD%/*} | grep -oi ".*$1[^/]*")
    
          if [ -z "${dest}" ]; then
              echo "up: could not find path matching *$1*"
              return 2
          fi
      
          echo "up: changing directory to ${dest}"
          cd "${dest}"
      }

------
shellkr
I have the below for cases when I have to make a quick screencast. It needs
ffmpeg and I am not sure how well the yt flag works as I don't really use
Youtube any longer. Anyway.. first I do 'ffsc sc' and if I want that video to
be smaller I do 'ffsc yt <path_to_file>'.

## Make screencast or convert to yt

ffsc () {

vid_name="$HOME/Videos/Screencasts/screencast_$(date +'%y%m%d-%H%M%S')"

    
    
            case $1 in
                    sc) ffmpeg -f x11grab -s 1920x1080 -i $DISPLAY -r 30 -f alsa -i default -preset ultrafast \
                        -c:v ffvhuff -c:a flac ${vid_name}.mkv
                        printf "${vid_name}.mkv" | xsel -i
    
                        echo
                        echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
                        echo "Output file name: ${vid_name}.mkv"
                        echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
                        echo
    
                        [ -e /tmp/ffsc.tmp ] && { rm /tmp/ffsc.tmp }
                        printf "${vid_name}.mkv" > /tmp/ffsc.tmp
                    ;;
                    yt) ffmpeg -i $2 -c:v libx264 -crf 18 -preset slow -pix_fmt rgb24 -c:a copy ${2/scr/yt_scr}
                        yt_name=$(cat /tmp/ffsc.tmp)
                        printf "${yt_name/scr/yt_scr}" | xsel -i
    
                        echo
                        echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
                        echo "Output file name: ${yt_name/scr/yt_scr}"
                        echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
                        echo
                    ;;
    
                    mini) ffmpeg -i $2 -strict -2 -s 1680x1050  -r 60 -c:v libx264 -b:v 164 -crf 22 -preset slow \
                          -pix_fmt yuv420p -c:a copy -an ${2/scr/mini_scr}
                          mini_name=${2/scr/mini_scr}
                          ffmpeg -i ${mini_name} -filter:v "setpts=0.5*PTS" -an ${mini_name/.mkv/.mp4}
                          rm ${mini_name}
                        printf "${mini_name/.mkv/.mp4}" | xsel -i
    
                        echo
                        echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
                        echo "Output file name: ${mini_name/.mkv/.mp4}"
                        echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
                        echo
                    ;;
            esac

}

And another nice one I didn't see here..

# Python as a calculator

pc() { python -c "print($*)"; }

------
kaustyap
From my .vimrc

set incsearch

set hlsearch

set ts=4

set smartindent

set tags=./tags;/

------
cfusting
set -o vi.

------
lowry
Truncate the $PWD to ¼ of the terminal width and put the result into the
command prompt:

    
    
        # truncate the $PWD
        function cut_pwd
        {
          newPWD="${PWD/#$HOME/\~}"
          local pwdmaxlen=$((${COLUMNS:-80}/4))
          if [ ${#newPWD} -gt $pwdmaxlen ]
          then
             newPWD=".+${newPWD: -$pwdmaxlen}"
          fi
        }
    
        PROMPT_COMMAND=cut_pwd
        PS1="\h:\${newPWD} \\$ "

------
Reimersholme
Sudo re-run last command.

alias hadouken='sudo $(history -p !!)'

~~~
tcbasche
Wouldn't this take longer to type out than `sudo !!` ?

------
jstewartmobile
vi-style line-editing

    
    
        set -o vi
    

emacs-style line-editing

    
    
        set -o emacs

------
yaccz
alias grr="grep -r --exclude-dir=.git"

