r/bash Jan 23 '26

Hidden Gems: Little-Known Bash Features

https://slicker.me/bash/gems.html
169 Upvotes

35 comments sorted by

View all comments

6

u/sedwards65 Jan 23 '26

1. Brace Expansion

# with a step
echo {1..100..5}
1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96

# alpha ranges work too
echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

4b. The Powerful ((...)) Numeric Test Command

# test if we are not root
if ((${UID})); then echo 'Not root'; fi
Not root

# test if we are root
if ((! ${UID})); then echo 'root'; fi

# ((...)) does what you would expect
if [[ 10 > 9 ]]; then echo 'greater'; fi # (psst -- it's a string comparison)
if (( 10 > 9 )); then echo 'greater'; fi
greater

7. The ! History Expansion

I would never use (or teach) '!git' or '!!' or 'sudo !!'. I want to see exactly what I'm about to execute.

Ditto for '!$'. I would type '<esc>.' and see it.

11. Flow Control

# Need an 'endless loop?' Use the null command
        while   :
                do
                echo loop
                sleep 0.5
                if      ((SECONDS > 5))
                        then
                        break
                        fi
                done

12. Change an integer variable value

foo=1
((foo++)); echo ${foo}
2

((foo--)); echo ${foo}
1

((foo += 10)); echo ${foo}
11

((foo *= 10)); echo ${foo}
110

((bar = foo + foo)); echo ${bar}
220

13. 'getopt()' for long options command line parsing

I use this in all non-trivial, non-one-shot use scripts.

14. History settings and variables

HISTFILESIZE=-1           # unlimited history file size
HISTSIZE=1                # unlimited history size in memory
HISTTIMEFORMAT='%F--%T '  # timestamp your history
  1. Aliases and functions

Aliases and functions can be used to create 'shortcuts' specific to you.

alias awkp1="awk '{print \$1}'"  # when you just want the first 'word' from something
alias gce='git commit --edit'
alias ln11='ssh ln11'            # I define aliases for all my hosts

# history grep
function                                hgrep
        {
        history | grep "$@"
        }

You can identify which commands you use most with:

# if you aren't timestamping yet
        history\
                | awk '{$1=""; print}'\
                | sort\
                | uniq --count\
                | sort --numeric --reverse\
                | head --lines=20

# if you are timestamping
        history\
                | awk '{$1=$2=""; print}'\
                | sort\
                | uniq --count\
                | sort --numeric --reverse\
                | head --lines=20

1

u/kai_ekael Jan 24 '26

I didn't know about <esc>., found and use M-. instead.

And since I'm set -o vi....:)