How to save frequently used terminal commands (SSH snippets)

Start with the history your shell already keeps: raise HISTSIZE, add timestamps, and find old commands with Ctrl-R. Add a comment such as # @health to a command and you can search for the tag later. Turn the commands you use every week into aliases or functions in one file that you copy to each server. Keep passwords and tokens out of all of it.

Updated . bash 5.2 settings, HISTIGNORE, history -d, aliases, functions and RemoteCommand were run on Debian 13 containers with OpenSSH 10.0.

Your shell already saves them

Every command you type is kept in the shell history, but the defaults are small and the file is written only when the shell exits. Two sessions at once can overwrite each other's lines. For bash, add this to ~/.bashrc:

HISTSIZE=100000
HISTFILESIZE=100000
HISTCONTROL=ignoreboth
HISTTIMEFORMAT='%F %T '
shopt -s histappend
PROMPT_COMMAND='history -a'
  • HISTSIZE and HISTFILESIZE keep up to 100,000 lines in memory and in the file.
  • ignoreboth skips repeated lines and lines that start with a space.
  • HISTTIMEFORMAT adds the date and time to history.
  • histappend and history -a add each command to the file right away, so a lost connection loses nothing. If your PROMPT_COMMAND already has a value, add history -a; in front of it.

For zsh, the default on macOS, put this in ~/.zshrc:

HISTFILE=~/.zsh_history
HISTSIZE=100000
SAVEHIST=100000
setopt EXTENDED_HISTORY INC_APPEND_HISTORY HIST_IGNORE_SPACE HIST_IGNORE_DUPS

Do the same on the servers you use most. Over SSH, the history is saved on the server, for the user you logged in as.

Find a command again

Press Ctrl-R and type any part of the command. Press Ctrl-R again for older matches, Return to run, or an arrow key to edit first. To see a list instead:

history | grep journalctl

With the timestamps set above, the list shows when each command ran:

    1  2026-11-06 15:21:40 echo one
    2  2026-11-06 15:21:40 diskfree /tmp
    3  2026-11-06 15:21:40 uptime -p  # @health

The last line shows a useful trick. A comment after # does nothing when the command runs, but it stays in the history. Add a tag such as # @health or # @deploy, and Ctrl-R then @health finds every command you tagged that way.

Aliases and functions for the commands you repeat

A command you type every week deserves a short name. An alias is fixed text. A function can take arguments:

alias logs='journalctl -u nginx --since "1 hour ago" --no-pager'
diskfree() { df -h "${1:-/}" | tail -n 1; }

diskfree alone checks /, and diskfree /var checks that folder. Check what a name does with type logs. Aliases work only in interactive shells, so a script or ssh server logs will not find them. Use a function in a sourced file, or a small script in ~/bin, for those cases.

A saved command per server in your SSH config

For a command you always run on one server, such as following a log, the SSH config can run it on login. Put this in ~/.ssh/config:

Host web1-logs
  HostName web1
  RemoteCommand tail -f /var/log/nginx/error.log
  RequestTTY yes

ssh web1-logs then opens the log directly. RequestTTY yes gives the command a terminal, so Ctrl-C works. The entry cannot also take a command on the command line: ssh web1-logs uptime fails with Cannot execute command-line and remote command. Override it when you need to:

ssh -o RemoteCommand=none web1-logs uptime

More patterns are in the ssh config file guide.

Keep them in one file you can carry

Put your aliases and functions in their own file, load it from your shell configuration, and copy it to the servers you use:

mkdir -p ~/.config/shell
$EDITOR ~/.config/shell/commands.sh
echo '[ -f ~/.config/shell/commands.sh ] && . ~/.config/shell/commands.sh' >> ~/.bashrc
ssh web1 'mkdir -p ~/.config/shell' && scp ~/.config/shell/commands.sh web1:.config/shell/

Add the same echo line to the server's ~/.bashrc once. Keeping the file in a git repository gives you its history and an easy way to bring it to a new machine. To send it to many servers at once, see how to run a command on multiple servers.

What never to save

History files are plain text. A password typed on the command line, such as mysql -pS3cret, stays there for anyone who can read the file. Three ways to keep secrets out:

  • Start the line with a space. With ignoreboth in bash or HIST_IGNORE_SPACE in zsh, it is not saved.
  • Skip patterns for good with HISTIGNORE in bash:
HISTIGNORE='*PASSWORD*:*TOKEN*'
  • Remove a line you just typed. In bash 5 or later, this deletes the command before it:
history -d -2

That only fixes the history in memory. If the line already reached the history file, delete it there too, and change the password, because it may already have been copied elsewhere. Better still, let the program ask for the password, with mysql -p and nothing after it, or read secrets from a file with strict permissions.

Questions

Where does bash save my command history?

In ~/.bash_history, written when the shell exits unless you add history -a to PROMPT_COMMAND. zsh uses the file in HISTFILE, often ~/.zsh_history.

Does the history on a server include my local commands?

No. Each machine keeps its own history. Commands you type in an SSH session are saved on the server, in the history of the user you logged in as.

How do I stop a command from being saved?

Start it with a space when HISTCONTROL contains ignorespace in bash, or HIST_IGNORE_SPACE is set in zsh. HISTIGNORE can also skip patterns such as *TOKEN*.

What is the difference between an alias and a function?

An alias replaces the first word of a command with fixed text. A function is a small program that can take arguments, such as a folder or a service name.

Sources

More in Configuration and many servers

All guides