safe − a password manager for the command line


safe [-f file] [-i] [-E|-F] [-r] [--] pattern

safe -a [-f file] [--] [text]

safe -m [-f file] [--] [text]

safe -d [-f file] [--] text

safe -e [-f file] [-i] [-E|-F] [--] pattern

safe -s file [-f file]

safe -I file [-f file]

safe -h

safe -v


safe stores passwords or other secrets in an encrypted file. The file is encrypted with the user’s default GnuPG key. (That means the user must already have a private key for use with gpg(1) or gpg2(1).) A “secret” can be any arbitrary text. safe can add a secret, edit an existing secret, delete a secret or display a secret that matches some pattern. The pattern is a regular expression as in grep(1).

Retrieving secrets
To retrieve a secret, pass a pattern that matches any part of that secret. For example, if the store contains the secret “login.example.org marja17 pA55word”, a command like this could be used to find it:

safe example.org

safe will prompt for the passphrase that unlocks the user’s private key, searches the store with grep(1) and returns the matching secret(s). The private key is normally kept in memory for a short period by gpg(1), typically 20 minutes, so that the user doesn’t have to enter the passphrase on every invocation.

The grep options -i (case-insensitive search), -F (treat the pattern as a literal string instead of a basic regular expression) and -E (treat the pattern as an extended regular expression) are also supported. For example,

safe -i EXAMPLE.org

would find the same secret as above.

If the pattern starts with a dash, put two dashes (--) and a space in front of it. The -- signals to safe the end of the options and the start of the text or pattern.

Storing secrets
To add a secret, call safe with the -a option:

safe -a This is my secret text

The argument may have to be quoted if it contains characters that are special to the shell.

If you plan to use the -r option, the most secret word should be last on the line, e.g.:

safe -a example.org penny77 p@ssw0rd

Note, that putting a secret on the command line is unsafe.
Unless you have taken special measures, the command will be stored in
the command history. The command history is a file (for example,
that is readable by anybody with root access or anybody who has
physical access to the hard disk.

One solution is to omit the secret:

safe -a

This causes safe to prompt for the secret (“Enter data:”). It will only prompt for one line of text. If the secret consists of more than one line, use -m instead:

safe -m

safe will prompt for multiple lines (“End data with ^D:”). Enter all the lines and end by typing Control-D at the start of a line.

If you are using Bash, there are also ways to keep certain commands from being added to the command history. See the HISTCONTROL and HISTIGNORE variables in the bash(1) manual.

Deleting a secret
To delete a secret, use -d:

safe -d login.example.org marja17 pA55word

The text must exactly match the secret (that is, it is not a grep(1) pattern). It is a good idea to quote it, to avoid that the shell interprets special characters (“?”, “*”, etc.).

Editing a secret
You can modify an existing secret in a text editor with the -e option. For example:

safe -e EXAMPLE.org

safe will find all matching secrets and open a text editor. Each secret ends with a line that says “DO NOT EDIT THIS LINE”. Don’t remove that line, or safe will not be able to find the beginning and end of the text of each secret.

Dealing with multiple stores: importing and synchronizing
can add the secrets from one store to another. If “othersafe” is a store, then

safe -I othersafe

will import all the secrets from “othersafe” that do not already exist in the local store. (I.e., it will not create any duplicates.)

If you have rsync installed, the “othersafe” may also be on another machine, e.g.

safe -I my.host.com:.safe

Use the -f option to specify an explicit store to import into, instead of the default one.

Another way to synchronize two stores is with the -s (synchronize) option. This opens an interactive editor showing the differences between the local store and the other store so you can select exactly what you want to add. Afterwards, the two stores will be the same. This works best with two stores that are already mostly the same. See the description of -s below for details.


safe accepts the following command line options:


(“Add”) The text is added to the store of secrets. If text is missing or empty, safe prompts for it and then reads a line of text from the standard input.

Adding a secret that already exists is not an error, but has no effect either.

See the remark under “Storing secrets” above about the risks of typing a secret on the command line.


(“Multi-line add”) The text is added to the store of secrets, the same as with the -a option. However, when text is omitted or empty, safe prompts for multiple lines of text. It reads text lines from the standard input until a Control-D (end of file).


(“Delete”) The text is deleted from the store of secrets. The text must exactly match the whole secret. You cannot use a pattern.


(“Edit”) This option causes safe to find all secrets that match pattern and open them in a text editor. You can edit them and when you close the editor, safe writes the modified secrets back to the store.

The environment variables VISUAL and EDITOR (in that order) determine the editor that safe uses. If neither defines a valid editor, safe exits with an error.


(“case-Insensitive”) This option causes safe to ignore case in pattern: Uppercase letters in the pattern can match lowercase letters in a secret or the other way round. For example, the pattern “Foo” matches a secret that contains “FOO”, but also “foo”, “fOO”, etc.


(“Fixed string”) safe interprets the pattern as a literal string instead of a regular expression. Characters such as “.”, “[” and “*” are not special, but stand for themselves.


(“Extended regular expression”) The pattern is interpreted as an extended regular expression. See grep(1) for the syntax of such expressions.


(“Red”) Prints the last word of every output line in red on red (on terminals that support color). That means the word is not readable for anybody looking at the screen, but it can still be copied and pasted (if in an environment that supports selecting text for copy-paste). Only the last word on each line is printed red on red, so for this to be useful, the secrets should have the most secret word (such as a password) last.

-s file

(“Synchronize”) Compares the store file with the default store (or the store given by the -f option). If there are differences, safe opens an editor with the combined secrets from both stores. Differences are marked between “<<<<<<<” and “>>>>>>>”. (This is created with the diff3(1) program). If you resolve the differences and remove all “<<<<<<<”, safe will make both file and the default store (or the store given by -f) equal to this edited file. But if any “<<<<<<” are left, the stores will not change. The file may be on a remote machine, specified as host:file (This requires rsync(1) to be installed. See there for details of how to specify remote files.)

-I file

(“Import”) Imports secrets from the encrypted store file into the default store (or the store given by the -f option). Duplicates of existing secrets are not imported. file may be on a remote machine, specified as host:file (This requires rsync(1) to be installed. See there for details of how to specify remote files.)

-f file

(“File”) The file that holds the secrets. The default file is ~/.safe


(“Help”) Prints a brief explanation of the options and then exits.


(“Version”) Prints the program name and version number and then exits.


safe returns 0 on success, 1 on error. It is an error if safe finds no matches for pattern. although it prints no error message in that case.


safe uses the following environment variables:


The name or path of the text editor to use for the -e and -s options.


The name or path of the text editor to use for the -e and -s options, if VISUAL does not contain a valid editor.


By default, safe looks for gpg(1) and gpg2(1) in the PATH. If the local gpg program is not in the PATH or it is called something else, the environment variable GPG can be set to the correct path, e.g., “GPG=/home/jean/bin/gpg”.


Extra command line options for the gpg or gpg2 command.

For the environment variables used by gpg(1), see its manual page.



The default file for stored secrets.


The latest version of safe can be found at www.phonk.net.


Security of the -e and -s options
The options -e and -s make use of a temporary file that contains secrets in plain text (i.e., not encrypted). Another user with sufficient privileges will be able to read that file while the user of safe is editing it. The file will be shredded with shred(1) to remove its contents before deleting it, but if shred is not installed, if the system crashes while the file is being edited, or if the /tmp directory is located on a file system on which shred is not effective (such as a journaled file system), then parts of the contents may remain on disk or in memory.

Pinentry programs and running on a remote machine
To decrypt a store, safe calls gpg, which in turn calls a program called gpg-agent to unlock the user’s secret key, which in turn may call a program called pinentry to prompt the user for the passphrase that unlocks the secret key. Normally, if you have gpg installed, the others are installed as well. However, there are several variants of pinentry, including pinentry-gnome3, pinentry-qt, pinentry-qt4, pinentry-tty, pinentry-x11 and pinentry-curses, of which typically only one is installed. If you log in to a remote machine over SSH and run safe in a terminal there, gpg-agent needs pinentry-tty or pinentry-curses. If they are not available, the symptom is typically that safe does nothing for several seconds and then fails with the message “gpg: decryption failed: No secret key”. Installing pinentry-tty or pinentry-curses should solve the problem. If not, another workaround is to set

GPGOPTS="--pinentry-mode loopback"

This tells gpg-agent to not use the pinentry program, but let gpg itself ask for the passphrase.


None known yet.


gpg(1), grep(1), bash(1), diff3(1), rsync(1)