Bash is a powerful command-line shell that can be used to perform a wide range of tasks, from managing files and directories to automating system administration. By learning a few simple tips and tricks, you can significantly boost your productivity and efficiency when using Bash.
Here are a few of my favorite Bash tips and tricks, in a randomized order:
-
Use Ctrl+R to search your command history as you type. This is a great way to quickly find and reuse previous commands.
-
Use
shopt -s cdspellto automatically fix yourcd folderspelling mistakes. This can save you a lot of time and frustration, especially if you are working with directories with long or complex names. -
Use
!!:nto select the nth argument of the last command, and !$ to select the last argument. For example,ls file1 file2 file3; cat !!:1-2will show all files and then cat only the first two files. -
Input from the command line as if it were a file by replacing
command < file.inwithcommand <<< "some input text". This can be useful for piping input into commands or for providing input to scripts. -
Use the ^ (caret) operator to replace characters from the last command. For example,
ls docs; ^docs^webis equal tols web. The second argument can be empty. -
Use !! to expand to the last typed command. This is useful for root commands that require sudo privileges. For example, if you type
cat /etc/...and get a permission denied error, you can simply typesudo !!to retry the command with sudo privileges. -
Use traps for cleaning up Bash scripts on exit. This is especially important for scripts that perform destructive operations, such as deleting files or modifying system settings.
-
Use
nohup ./long_script &to leave stuff running in the background even if you logout. This is useful for long-running tasks such as backups or data processing jobs. -
Use
shopt -s histverify histreeditin your ~/.bashrc to double-check all expansions before submitting a command. This can help to prevent errors from typos or unexpected expansions. -
Use Esc-. to fetch the last parameter of the previous command. This can be useful for quickly reusing parameters in complex commands.
-
Use Ctrl+X Ctrl+E to open an editor to work with long or complex command lines. This can be useful for debugging commands or for testing different options.
Where These Tricks Actually Break
Here’s the thing nobody puts in the tips post: half of these will silently not work depending on how your shell is configured, and you’ll spend 20 minutes convinced you’re doing it wrong.
!! and history expansion don’t work in scripts. They’re interactive-only. If you paste sudo !! into a script, you’re not running the last command — you’re passing a literal !! to sudo, which will do nothing useful and complain loudly about it.
histverify and histreedit need HISTFILE to be set. If you’re on a machine where history is disabled (some hardened servers, CI containers), those shopt options load fine but do absolutely nothing. Silent failure. Love that for us.
Ctrl+R exits with the wrong binding in some terminals. If Ctrl+R opens reverse-i-search but Ctrl+G doesn’t cancel it, your $TERM or readline bindings are off. Add this to ~/.inputrc to normalize it:
"\C-g": abort"\C-r": reverse-search-historyEsc-. breaks if you’re in vi mode. Bash supports both emacs and vi keybindings. Esc-. is an emacs binding. If you or some tool ran set -o vi, you’re now in vi insert mode and Esc drops you to command mode — . there repeats the last edit, not the last argument. Check with set -o | grep -E 'vi|emacs'.
The trap Gotcha That’ll Bite You
trap is great for cleanup, but there’s a common footgun: if you define your trap after a subshell launches, the subshell doesn’t inherit it. Traps are not exported.
#!/usr/bin/env bash# This workstrap 'rm -f /tmp/lockfile' EXIT
# This does NOT propagate the trap into the subshell( echo "I'm a subshell, trap won't run here on exit" exit 1)If your cleanup logic needs to run inside a subshell too, define the trap inside it. Or better, don’t rely on subshell traps for anything critical — use a top-level trap and clean up by reference after the subshell returns.
The shortcuts are real time-savers once they’re in muscle memory. Just don’t assume any of them work everywhere until you’ve confirmed your environment actually has them set up.