21 KiB
psql CLI Options, Variables & Environment
Complete reference for psql command-line flags, configuration variables, and environment variables.
Table of Contents
- CLI Options
- Connection Parameters
- Input/Output Options
- Output Format Options
- psql Variables
- Environment Variables
- Configuration Files
- Tab Completion
- Editor Integration
CLI Options
Synopsis
psql [option...] [dbname [user]]
When dbname is the first non-option argument, it specifies the database. The second non-option argument specifies the user.
General Options
| Flag | Description |
|---|---|
-a / --echo-all |
Print all nonempty input lines to stdout as they are read. Equivalent to ECHO=all. |
-b / --echo-errors |
Print failed SQL commands to stderr. Equivalent to ECHO=errors. |
-c command / --command=command |
Execute one or more SQL commands, then exit. Commands can be separated by semicolons. Each -c string is sent as a single request — multiple SQL commands within it execute in one transaction (unless explicit BEGIN/COMMIT). Cannot mix SQL and meta-commands in one -c. Returns 0 on success, 1 on error, 2 if connection fails. |
-d dbname / --dbname=dbname |
Database name to connect to |
-e / --echo-queries |
Copy all SQL commands sent to the server to standard output as well |
-E / --echo-hidden |
Echo hidden queries (the SQL generated by \d commands and other meta-commands) to stderr. Useful for learning how psql works internally. |
-f filename / --file=filename |
Execute commands from file, then exit. Use - for stdin (reads until EOF or \q; Readline not available). -f provides line-numbered error messages unlike shell redirection. |
-F separator / --field-separator=separator |
Field separator for unaligned output (default: ` |
-H / --html |
HTML output mode |
-l / --list |
List available databases, then exit. Connects to postgres database unless a different database is specified via -d or a non-option argument. |
-L filename / --log-file=filename |
Log all session output to file |
-n / --no-readline |
Disable enhanced command-line editing and tab completion |
-o filename / --output=filename |
Redirect all query output to file |
-P assignment / --pset=assignment |
Set printing option (format: option=value) |
-q / --quiet |
Quiet mode — no startup message, no informational messages |
-R separator / --record-separator=separator |
Record separator for unaligned output (default: newline) |
-s / --single-step |
Single-step mode. Confirm before each command is sent to the server. |
-S / --single-line |
Single-line mode. Newline terminates a query (as if semicolon). Not recommended — execution order can be unclear when mixing SQL and meta-commands on the same line. |
-t / --tuples-only |
Print rows only — no headers, footers |
-T table_options / --table-attr=table_options |
HTML table attributes |
-v assignment / --set=assignment / --variable=assignment |
Set psql variable (format: name=value sets, name unsets, name= sets to empty). Assignment happens at command-line processing time, so connection-state variables are overwritten later. |
-V / --version |
Print psql version and exit |
-w / --no-password |
Never issue a password prompt. Fails if password is required. Setting persists for the entire session, including \connect attempts. |
-W / --password |
Force password prompt. Setting persists for the entire session, including \connect attempts. |
-x / --expanded |
Turn on expanded table output |
-X / --no-psqlrc |
Do not read the startup file (~/.psqlrc) |
-z / --field-separator-zero |
Set field separator to NUL byte |
-0 / --record-separator-zero |
Set record separator to NUL byte |
-1 / --single-transaction |
Wrap -f or -c commands in a single transaction. If any command fails, all roll back. Warning: if the script itself contains BEGIN/COMMIT/ROLLBACK, this option will not have the expected effect. |
-? / --help[=topic] |
Show help. topic can be commands (backslash commands), options (CLI options, default), or variables (config variables). |
--csv |
Switch to CSV output mode. Equivalent to \pset format csv. |
Connection Parameters
These options control how psql connects to PostgreSQL.
| Flag | Env Variable | Description |
|---|---|---|
-h host |
PGHOST |
Host name or socket directory (default: local socket) |
-p port |
PGPORT |
Port number (default: 5432) |
-U user |
PGUSER |
Database user name |
-d dbname |
PGDATABASE |
Database name |
-w |
— | Don't prompt for password |
-W |
— | Force password prompt |
Connection URI:
psql postgresql://user:password@host:5432/dbname?sslmode=require
psql postgresql:///dbname?host=/var/run/postgresql
Service lookup: If PGSERVICE or service=name in connection string is set, psql reads connection parameters from pg_service.conf.
Input/Output Options
| Flag | Description |
|---|---|
-c command |
Execute command(s) then exit. Multiple commands separated by ;. |
-f filename |
Read commands from file then exit. Use - for stdin. |
-1 |
Run in a single transaction (only effective with -c or -f) |
-a |
Echo all input lines to stdout |
-b |
Echo failed SQL to stderr |
-e |
Echo queries to stdout |
-E |
Echo hidden queries (\d internals) to stderr |
-L file |
Log all output to file |
-o file |
Redirect output to file |
-n |
Disable readline |
Common patterns:
# Run a migration in a transaction
psql -1 -f migration.sql mydb
# Execute a single query
psql -c "SELECT count(*) FROM users" mydb
# Pass a variable from the command line
psql -v table=users -c 'SELECT count(*) FROM :"table"' mydb
# Batch process with for-loop
for f in /tmp/*.sql; do psql -1 -f "$f" mydb; done
# Echo internal queries to learn psql
psql -E mydb -c "\d+ users"
Output Format Options
| Flag | Description |
|---|---|
-A / --no-align |
Unaligned (delimiter-separated) output |
-F sep |
Field separator (default: ` |
-H / --html |
HTML table output |
-P opt=val |
Set pset option (e.g., -P pager=off) |
-R sep |
Record separator (default: newline) |
-t |
Tuples only (no headers/footers) |
-T attrs |
HTML table attributes |
-x |
Expanded display |
-z / -0 |
NUL separators |
Script-friendly output pattern:
# CSV output
psql --csv -c "SELECT id, name FROM users" mydb
# Custom delimiter output
psql -A -F ',' -t -c "SELECT id, name FROM users" mydb
# NUL-separated for xargs -0
psql -A -z -t -c "SELECT filename FROM files_to_process" mydb | xargs -0 process
# JSON-friendly (one value per line)
psql -A -t -c "SELECT json_agg(row_to_json(t)) FROM (SELECT id, name FROM users) t" mydb
psql Variables
psql maintains internal variables that control behavior. Set with \set, unset with \unset, view all with \set (no arguments).
Automatic Variables
| Variable | Description |
|---|---|
AUTOCOMMIT |
on (default) or off. When off, psql auto-issues implicit BEGIN before any command not in a transaction block (except BEGIN/VACUUM etc.). You must explicitly COMMIT or ROLLBACK. |
COMP_KEYWORD_CASE |
lower, upper, preserve-lower (default), preserve-upper. Controls tab-completion keyword casing. preserve-lower/preserve-upper preserves case of already-typed input; empty input completes as lower/upper case. |
DBNAME |
Current database name. Set automatically on connect. |
ECHO |
none (default), all, queries, errors. Controls what gets echoed. all echoes all commands (including scripts). queries echoes only SQL queries, not meta-commands. errors echoes failed SQL commands to stderr (set by -b). |
ECHO_HIDDEN |
off, on, noexec. When on, shows hidden queries (SQL behind \d commands). noexec shows them without executing. |
ENCODING |
Current client encoding. Set automatically. |
ERROR |
true if the last query failed, false otherwise. |
FETCH_COUNT |
Integer (default: 0). When set, psql fetches rows in batches of this size instead of all at once. Useful for large result sets. |
HIDE_TABLEAM |
If set, hide table access methods in \d+ output. |
HIDE_TOAST_COMPRESSION |
If set, hide compression method in \d+ output. |
HISTCONTROL |
none (default), ignorespace, ignoredups, ignoreboth. Controls history saving. |
HISTFILE |
Path to history file (default: ~/.psql_history). Can include psql variable references, e.g. \set HISTFILE ~/.psql_history-:DBNAME. |
HISTSIZE |
Maximum number of history entries (default: 500). A negative value disables the limit. |
HOST |
Current server host. Set automatically on connect. |
IGNOREEOF |
If set, prevents Ctrl-D from exiting. Value is the number of EOFs to ignore before quitting. |
LAST_ERROR_MESSAGE |
Error message from the last failed query. |
LAST_ERROR_SQLSTATE |
SQLSTATE error code from the last failed query (00000 if no error). |
LASTOID |
OID of the last affected row by INSERT or \lo_import. Always 0 for PG 12+ tables (OID column removed). |
ON_ERROR_ROLLBACK |
off (default), on, interactive. When on, errors inside a transaction create savepoints automatically, allowing continued execution. interactive only activates in interactive sessions, not when reading scripts. |
ON_ERROR_STOP |
off (default) or on. When on, a query error or meta-command error stops script execution and exits. Critical for safe scripting. |
PIPELINE_COMMAND_COUNT |
Number of queued commands in current pipeline. |
PIPELINE_RESULT_COUNT |
Number of commands with pending results in current pipeline. |
PIPELINE_SYNC_COUNT |
Number of queued sync messages in current pipeline. |
PORT |
Current server port. Set automatically on connect. |
PROMPT1, PROMPT2, PROMPT3 |
Prompt format strings (see below). |
QUIET |
on or off. Quiet mode. |
ROW_COUNT |
Number of rows affected by the last query. |
SERVER_VERSION_NAME |
Server version string. |
SERVER_VERSION_NUM |
Server version as integer (e.g., 160000 for 16.0). |
SERVICE |
Service name from the connection, if applicable. |
SHELL_ERROR |
true if the last shell command (\!, \g, \o, \w, \copy, backquote) failed, false otherwise. |
SHELL_EXIT_CODE |
Exit code of the last shell command (0-127 normal exit, 128-255 signal termination, -1 launch failure). |
SHOW_ALL_RESULTS |
on (default) or off. When on, show all results from combined queries. |
SHOW_CONTEXT |
never, errors, always. Controls display of CONTEXT: in messages. Default: errors. |
SINGLELINE |
on or off. Newline acts as query terminator. |
SINGLESTEP |
on or off. Confirm before each command. |
SQLSTATE |
SQLSTATE error code from the last query. |
USER |
Current database user. Set automatically on connect. |
VERSION |
psql client full version string. |
VERSION_NAME |
psql client short version (e.g., 18beta1). |
VERSION_NUM |
psql client version as integer (e.g., 180000). |
WATCH_INTERVAL |
Default interval (seconds) for \watch command (default: 2). |
VERBOSITY |
default, verbose, terse, sqlstate. Controls error message detail level. |
SQL Interpolation
psql variables can be interpolated into SQL statements using colon-prefixed syntax. This is plain text substitution, not parameterized queries — understand the differences to use it safely.
| Syntax | Behavior | Example |
|---|---|---|
:varname |
Unquoted substitution. The variable's value replaces :varname literally, which can break SQL syntax or enable injection if the value contains special characters. |
\set table users → SELECT * FROM :table; → SELECT * FROM users; |
:'varname' |
Single-quoted string substitution. The value is placed inside single quotes, with any embedded single quotes and backslashes escaped. This is the safest form for values. | \set name O'Brien → SELECT * FROM users WHERE name = :'name'; → SELECT * FROM users WHERE name = 'O''Brien'; |
:"varname" |
Double-quoted identifier substitution. The value is placed inside double quotes, with embedded double quotes doubled. Use this for table/column names. | \set col first name → SELECT :"col" FROM users; → SELECT "first name" FROM users; |
:{?varname} |
Variable existence test. Always expands — TRUE if defined, FALSE otherwise. Designed for use in \if conditions. |
\if :{?myvar} → true if myvar was set |
\:varname |
Escaped colon. The colon is not treated as a variable reference — :varname is passed through literally. |
SELECT \:not_a_var FROM t; → SELECT :not_a_var FROM t; |
Note: Variable interpolation does NOT occur inside quoted SQL literals or identifiers. Therefore ':foo' does not produce a quoted string from the variable (and wouldn't be safe even if it did — it can't handle embedded quotes properly). Use :'foo' instead.
Safety guidance: Always prefer :'varname' (quoted string) over :varname (unquoted) when substituting user-provided values. Unquoted substitution can break SQL syntax or enable injection. For the safest programmatic parameter passing, use \bind with the extended query protocol (which provides true parameterized queries).
Key Variables for Scripting
ON_ERROR_STOP — The most important variable for scripts. Set it in scripts to ensure they abort on the first error instead of continuing:
-- At the top of any script:
\set ON_ERROR_STOP on
-- Now any error stops execution
INSERT INTO users (id) VALUES (1);
INSERT INTO users (id) VALUES ('bad'); -- aborts here
INSERT INTO users (id) VALUES (2); -- never reached
AUTOCOMMIT — Turn off to manually manage transactions:
\set AUTOCOMMIT off
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
\set AUTOCOMMIT on
FETCH_COUNT — For very large result sets that would consume too much memory:
\set FETCH_COUNT 1000
SELECT * FROM huge_table;
ERROR / SQLSTATE / LAST_ERROR_MESSAGE — For conditional logic:
INSERT INTO unique_table (id) VALUES (1);
\if :ERROR
\echo 'Insert failed: ' :LAST_ERROR_MESSAGE
\else
\echo 'Insert succeeded, rows affected: ' :ROW_COUNT
\endif
Prompt Customization
PROMPT1 is the normal prompt (default: '%/%R%x%# '). PROMPT2 appears when a command is incomplete (continuation) (default: '%/%R%x%# '). PROMPT3 appears during COPY FROM STDIN when row values are needed (default: '>> ').
Format specifiers:
| Spec | Output |
|---|---|
%/ |
Current database name |
%~ |
Like %/ but ~ if the database is your default database |
%m |
Host name (truncated at first dot), or [local] for Unix sockets |
%M |
Full host name, [local:/dir/name] for non-default Unix sockets |
%> |
Port number |
%n |
User name |
%s |
Service name (from connection) |
%# |
# if superuser, > otherwise |
%p |
Process ID of the server backend |
%R |
PROMPT1: = normally, ^ in single-line mode, @ if conditional stack inactive (e.g., inside skipped \if), ! if not connected. PROMPT2: - (continuation), * (comment), ' (single-quoted), " (double-quoted), $ (dollar-quoted), ( (parenthesized). PROMPT3: empty. |
%w |
Whitespace matching the visible width of the last PROMPT1 output (for aligning PROMPT2) |
%x |
Transaction status: empty (idle), * (in transaction block), ! (failed transaction), ? (unknown or no connection) |
%l |
Line number inside the current statement, starting from 1 |
%P |
Pipeline status: on (pipeline mode active), off (not in pipeline mode), abort (pipeline aborted) |
%% |
Literal % |
% digits |
Character with the given octal code (e.g., %033 = ESC character) |
%:varname: |
Value of psql variable |
%`[command]` |
Output of shell command (trailing newline stripped) |
%[ ... %] |
Tell Readline that the contained text is invisible (for ANSI escape codes) |
Common prompt configurations:
-- Show database and user
\set PROMPT1 '%n@%m %/%R%# '
-- Show transaction status
\set PROMPT1 '%/%x%# '
-- Production-safe prompt (color-coded)
-- Note: %033 is octal for ESC character; %[...%] tells Readline these chars are invisible
\set PROMPT1 '%[%033[1;31m%]%/%[%033[0m%]%R%# '
Environment Variables
| Variable | Description |
|---|---|
PGDATABASE |
Default database name |
PGHOST |
Default host (or socket directory) |
PGPORT |
Default port (5432) |
PGUSER |
Default user |
PGPASSWORD |
Password (not recommended — use ~/.pgpass instead) |
PGPASSFILE |
Path to password file (default: ~/.pgpass) |
PGSERVICE |
Service name from pg_service.conf |
PGSERVICEFILE |
Path to service file |
PGOPTIONS |
Default options to pass to the server |
PGSSLMODE |
SSL mode (disable, allow, prefer, require, verify-ca, verify-full) |
PGREQUIRESSL |
Legacy SSL flag (use PGSSLMODE instead) |
PGSSLCERT |
Client certificate path |
PGSSLKEY |
Client key path |
PGSSLROOTCERT |
Root certificate path |
PGSSLCRL |
Certificate revocation list path |
PGREQUIREPEER |
Require peer username for Unix socket connections |
PGKRBSRVNAME |
Kerberos service name |
PGGSSLIB |
GSS library to use |
PGCONNECT_TIMEOUT |
Connection timeout in seconds |
PGCLIENTENCODING |
Client encoding (overrides auto-detected locale setting) |
PGDATESTYLE |
Date display format |
PGTZ |
Time zone |
PGSYSCONFDIR |
System config directory |
PG_COLOR |
Color output (auto, always, never) |
COLUMNS |
When \pset columns is 0, controls wrapped format width and the threshold for activating pager or switching to expanded auto mode |
PSQL_EDITOR |
Editor for \e, \ef, \ev. Takes precedence over EDITOR and VISUAL. |
PSQL_EDITOR_LINENUMBER_ARG |
Command-line argument for passing line numbers to the editor (default: +). E.g., set to --line for editors that use --line N syntax. |
PSQL_HISTORY |
Alternative history file path (overrides HISTFILE) |
PSQLRC |
Alternative .psqlrc location |
PSQL_PAGER |
Pager command (overrides PAGER) |
PSQL_WATCH_PAGER |
Pager command specifically for \watch output (overrides PSQL_PAGER and PAGER when set). Unix only. |
EDITOR / VISUAL |
Editor for \e, \ef, \ev (checked after PSQL_EDITOR) |
SHELL |
Shell for \! |
TMPDIR |
Temp directory for temp files |
LANG |
Locale (affects sorting, number formatting) |
The ~/.pgpass File
Store passwords securely instead of using PGPASSWORD:
# Format: hostname:port:database:username:password
# Use * as wildcard
localhost:5432:mydb:myuser:YOUR_PASSWORD
*:5432:*:admin:YOUR_PASSWORD
Permissions must be 0600: chmod 600 ~/.pgpass
Configuration Files
~/.psqlrc
Executed on every interactive psql startup (unless -X is used). Perfect for personal customizations:
-- ~/.psqlrc example
\set ON_ERROR_STOP on
\timing on
\pset null '(null)'
-- Custom prompt showing database and transaction status
\set PROMPT1 '%n@%m %/%x%# '
-- Shortcuts
\set HISTSIZE 10000
\set HISTCONTROL ignoredups
-- Show how long queries took
\echo 'Welcome to' :DBNAME
Version-specific psqlrc
Append - and the version number for version-specific configuration. psql reads the most specific match:
~/.psqlrc-18— applies for psql 18.x~/.psqlrc-18.3— applies specifically for psql 18.3- System-level:
psqlrc-18in thepg_config --sysconfdirdirectory
System-wide psqlrc
System-level psql configuration at pg_config --sysconfdir/psqlrc (use PGSYSCONFDIR to override). Applied before user ~/.psqlrc.
Windows paths
On Windows, user config is at %APPDATA%\postgresql\psqlrc.conf and history at %APPDATA%\postgresql\psql_history.
Tab Completion
psql provides intelligent tab completion for:
- SQL keywords
- Table, view, and column names
- Function names and arguments
- Schema-qualified names
\dcommand patterns
Tab completion sends queries to the server to fetch metadata. This can interfere with operations: e.g., after BEGIN, a tab completion query means SET TRANSACTION ISOLATION LEVEL is too late.
To disable tab completion permanently, add to ~/.inputrc:
$if psql
set disable-completion on
$endif
Or use -n to disable for a single session.
Editor Integration
\e, \ef, and \ev use the editor specified by:
PSQL_EDITORenvironment variable (highest priority)EDITORenvironment variableVISUALenvironment variable- Default:
vi(Unix),notepad.exe(Windows)
Use PSQL_EDITOR_LINENUMBER_ARG to control how line numbers are passed (default: +).
Useful editor settings:
export EDITOR='vim'
# or for VS Code:
export EDITOR='code --wait'
# or for nano:
export EDITOR='nano'