← Back to list

Your Terminal Is 10x More Powerful Than You’re Using It

The Bash shortcuts and tricks that shave hours off developer workflows — none of which require installing a single thing

Sabit in JavaScript in Plain English · 2026-06-04 12:04 · 51 claps · 8.4 min read paywalled
#programming #linux #bash #devops #coding
Open on Medium ↗
Wiki topics: 💻 · Programming ☁️ · DevOps & Cloud 🔓 · Open Source

Your Terminal Is 10x More Powerful Than You’re Using It

The Bash shortcuts and tricks that shave hours off developer workflows — none of which require installing a single thing

Photo by Stackie Jia on Unsplash

Photo by Stackie Jia on Unsplash

Most developers use their terminal like a typewriter.

Type a command. Press Enter. Retype it. Press Enter again. Ten minutes after, retype it from scratch again.

That’s the slow path. And almost nobody teaches the slow path. It’s just what you do when you don’t know there’s a better way.

Bash has had a better way by default for years. But who has got the time to explore all of them anyway?

One-character shortcuts that recall arguments across commands. Brace expansion that turns ten keystrokes into one. Process substitution that pipes things that can’t be piped. A strict mode that stops your scripts from silently destroying things.

None of it requires anything installed. It’s already on your machine. Linux, on macOS, and server you’ve SSH’d into.

Here are the eight that pay for themselves immediately.

The terminal looks primitive. That’s a disguise. Underneath it is one of the most expressive environments ever built for getting work done.

1. Ctrl + R — Search your entire command history in seconds

Every command you’ve ever typed is stored in ~/.bash_history.

It’s possible you’ve never query it except by hammering the up arrow dozens of times hoping to land on the right one. I can’t count how many times I’ve hammered the arrow keys to get back the right command.

Sometimes I give up on the arrow keys and forced to type a command again when the command I’m looking for is one I’ve used days ago.

However, with this shortcut, press Ctrl + R and start typing any word of a command you remember. Bash will instantly show you the most recent match.

Press Ctrl + R again to cycle to the one before it. Press Enter to run it. Press any arrow key (or left or right arrow key) to drop it onto the command line to run or edit first.

# Press Ctrl+R, then start typing
(reverse-i-search)`doc’: docker compose up -d — build

# Press Ctrl+R again — cycles to the previous match
(reverse-i-search)`doc’: docker exec -it mycontainer bash

# Press Enter to run it, or arrow key to edit it first

This works on Bash terminal, server, and macOS machine . Just the shell you already have.

Pause. Open your terminal right now. And try this out. It’s so cool.

When to use it: Any time you’re about to retype a long command from memory. Any time you ran something last week and need it again. It replaces 90% of up-arrow hammering.

2. !! and !$ — Reuse the last command, or just its last argument

That’s another two Bash power features.

Honestly, I just found them.

!! expands to the entire last command you ran. !$ expands to the last argument of the last command.

Bash understands these and do the lifting for you.

$ apt install nginx
Permission denied.

$ sudo !!
# Bash expands !! → sudo apt install nginx

# !$ — reuse the last argument of the previous command
$ mkdir -p /var/www/myapp/public
$ cd !$
# Bash expands !$ → cd /var/www/myapp/public
# You’re now inside the directory you just created.

# Another example
$ nano /etc/nginx/sites-available/mysite.conf
$ ln -s !$ /etc/nginx/sites-enabled/
# Creates the symlink without retyping the long path

When to use it: !! whenever you ran something and realize you need to prepend sudo. !$ whenever your next command operates on the same file or path as the last one — mkdir then cd, touch then vim, cp then diff.

3. cd - — Instantly toggle between two directories

Developer spends time jumping between two directories . It could be a source folder and a config folder, a project root and a deployment target, or a local file and a mounted volume. Or any other folder directories.

The usual thing to do is to retype both paths constantly.

cd - takes you back to wherever you were before your last cd. Run it again and you’re back. It’s a two-directory toggle built into every shell.

$ pwd
/home/user/projects/myapp

$ cd /etc/nginx/sites-available
# edit a config file

$ cd -
/home/user/projects/myapp
# Back in one keystroke. No path required.

$ cd -
/etc/nginx/sites-available
# Toggle back. Works both ways, indefinitely.

When to use it: Any time you’re bouncing between two directories repeatedly. Works across any file systems.

4. Brace Expansion {a,b,c} and {1..10} — Do in one line what used to take ten

Brace expansion is Bash generating multiple arguments from a single pattern. It looks like punctuation. It works like a loop. And it has no real equivalent in any GUI.

# Create multiple files at once
$ touch app.{html,css,js}
# Creates: app.html app.css app.js

# Back up a config file before editing it — the classic
$ cp /etc/nginx/nginx.conf{,.bak}
# Copies nginx.conf → nginx.conf.bak
# The comma with nothing before it means “original name + .bak”

# Create a full project directory structure in one shot
$ mkdir -p project/{src,tests,docs,dist}
# Creates: project/src project/tests project/docs project/dist

# Sequence expansion — create 100 numbered test files
$ touch test_{1..100}.log
# Creates: test_1.log test_2.log … test_100.log

# Compare before and after versions of the same file
$ diff /etc/nginx/nginx.conf{.bak,}
# Diffs nginx.conf.bak against nginx.conf
# No retyping the path twice

When to use it: When you want to create multiple related files or directories. Or backing up files before editing. Or comparing old and new versions. Or renaming files with a common prefix. And moving files to a new location with a different extension.

5. ${var:-default} ${str##*/} ${str%.ext} — String manipulation with no external commands

I get it. These commands can be hard to read or even remember. You don’t need to. With repetition, you automatically remember them.

It’s also good to keep a notebook to write these commands or reference them just in case you need them. Super important!

These are Bash built-in parameter expansion syntax that handles the most common case. They extract filenames, strip extensions, and set defaults in pure shell.

filepath=”/var/www/app/index.html”

# Extract just the filename (everything after the last /)
echo “${filepath##*/}” # → index.html

# Extract just the directory (everything up to the last /)
echo “${filepath%/*}” # → /var/www/app

# Strip the file extension
echo “${filepath%.html}” # → /var/www/app/index

# Replace a substring inline
echo “${filepath/html/php}” # → /var/www/app/index.php

# Default value if variable is unset or empty
ENV=””
echo “${ENV:-production}” # → production
# If ENV had a value, that value would be used instead.

# String length
name=”hello”
echo “${#name}” # → 5

When to use it: Any string operation you’d normally pipe through basename, dirname, or sed.

6. diff <(cmd1) <(cmd2) — Pipe things that can’t be piped

Some commands only accept filenames — not stdin.

If you want to compare the output of two commands, your usual option is to write them both to temporary files, diff the files, then delete the files.

Three extra steps for one logical operation.

Process substitution — the <(command) syntax tells Bash to run a command and present its output as if it were a file. You never create a file. Nothing is written to disk. It just works.

# Compare sorted contents of two directories — no temp files
$ diff <(ls dir1 | sort) <(ls dir2 | sort)

# Compare a live API response against a saved fixture
$ diff <(curl -s [https://api.example.com/users](https://api.example.com/users)) expected.json

# Compare packages installed on two servers
$ diff <(ssh server1 ‘dpkg -l’) <(ssh server2 ‘dpkg -l’)

# Diff your local .env against what’s in the environment
$ diff <(sort .env) <(env | sort)

# Check if two outputs are identical
$ diff <(command_a) <(command_b) && echo “identical” || echo “different”

When to use it: Any time you’d write to a temp file just to feed it to a command that demands a filename.

7. Ctrl + X, E — Edit the current command in your full text editor

When a command gets long such as a multi-stage pipeline, a complex find with several conditions, or a curl with a dozen flags, editing it inline in the terminal becomes awkward.

The cursor is small, mistakes are easy, and the line can wrap messily.

Press Ctrl + X then E and Bash opens whatever is on your command line in your default text editor ($EDITOR). Edit it comfortably. Save and quit. Bash runs the result immediately.

Are you thinking of what nano also do?

# Set your preferred editor (add to ~/.bashrc)
export EDITOR=vim # or nano, or code, or whatever you use

# When you have a long command on the line:
$ find /var/log -name “*.log” -mtime +30 -size +10M -type f

# Press Ctrl+X, E
# That command opens in vim (or your editor of choice)
# Edit it with full editor comfort: copy, paste, undo, multiline
# Save and quit → Bash runs the edited version

# Tip: also works on an empty line to compose a complex
# command from scratch in your editor before running it

When to use it: Any command that would benefit from more than one line of editing space.

8. set -euo pipefail — The three lines every script should start with

By default, Bash scripts have a shocking tolerance for failure.

When a command fails, the script keeps running. You reference a variable you never defined, and Bash uses an empty string and continues. A command in a pipeline fails but the pipeline reports success because the last command worked.

This is how Bash scripts silently corrupt data, half-deploy things, and cause production incidents that take hours to diagnose.

The failure happened on line 3. The error surfaces on line 47.

#!/bin/bash
set -euo pipefail
# Three flags. Here’s what each one does:

# -e → exit immediately when any command fails
some_command_that_fails
echo “Without -e, this still runs.” # ← dangerous
echo “With -e, the script exits above.”

# -u → treat unset variables as an error
# Without -u, a typo becomes a silent empty string:
echo “Deploying to: $ENVIROMENT” # typo — prints nothing
rm -rf “$DEPLOY_PATH/$ENVIROMENT” # DANGER: expands to rm -rf “$DEPLOY_PATH/”
# With -u: script exits the moment it hits the undefined $ENVIROMENT

# -o pipefail → catch failures inside pipelines
# Without pipefail:
grep “pattern” nonexistent_file.txt | sort | uniq > output.txt
# grep fails. sort succeeds. Exit code = 0. No error reported.
# output.txt is empty. Your script thinks everything worked.

# With -o pipefail:
# Exit code = grep’s non-zero code. Script halts. You find out.

The real danger of missing -u: Scripts that clean up directories, deploy to paths, or delete old builds are the ones where a typo in a variable name can turn rm -rf “$DEPLOY_PATH/$ENV” into rm -rf “/var/www/”because $ENV evaluated to empty. The -u flag stops the script before that happens.

When to use it: Every Bash script you write. No exceptions. Add it right below the shebang line. The only reason not to is if you’re intentionally handling errors manually. And if you are, you already know what you’re doing.

I’m changing my mind. So I’m adding the ninth!

9. Ctrl + Shift + or Ctrl + Shift + V — Copy or paste into the Terminal

The general shortcut to copy or paste anything, anywhere is to highlight what you want and press Ctrl + C or Ctrl + V.

However, the first time I tried this in the Terminal showed they work this way.

You must add the Shift key before pressing C or V. And that’s all.

When to use it: Anytime you want to copy or paste in the Terminal.

The Terminal Doesn’t Reward Ignorance

The developers who work effortlessly in the terminal aren’t faster typists. They only know there way. Period.

They know which four keystrokes replace twenty. They’ve stopped retyping things they already typed. They’ve stopped writing scripts that fail silently.

None of the nine tricks above are obscure. They’re in the Bash manual. They’ve been there for twenty years. They just don’t get taught in many tutorials.

Tutorials start at the beginning. These aren’t the beginning.

Start with Ctrl + R today. It will change how you use a terminal immediately, before you’ve tried anything else.

Come back for the rest when that one becomes a habit, like I encouraged earlier.

”The shell is a language. Most people learn to spell in it. The good ones learn to write.”

All eight tricks (plust one) work on any system with Bash. Check your version with bash — version. Anything 4.0+ supports everything listed here. macOS ships with Bash 3.2 by default — upgrade with brew install bash for full support.*


메타데이터
post_id
027ffa66c3e5
slug
your-terminal-is-10x-more-powerful-than-youre-using-it-027ffa66c3e5
url
https://javascript.plainenglish.io/your-terminal-is-10x-more-powerful-than-youre-using-it-027ffa66c3e5
canonical_url
https://javascript.plainenglish.io/your-terminal-is-10x-more-powerful-than-youre-using-it-027ffa66c3e5
author_url
https://medium.com/@tibas
status
ok
fetched_at
2026-06-10 09:45:17