New users frequently attempt to run PostgreSQL's command line utilities
from the psql prompt.
They tend to be confused when this appears to do absolutely nothing:
psql=> pg_restore
psql->
since they're generally not going to semicolon-terminate the command either.
The attached patch detects common command names when they appear first on a
new input line prints a help message. If the buffer is empty a more
detailed message is printed and the input is swallowed. Otherwise, much
like how we handle "help" etc,
a short message is printed and the input is still added to the buffer.
psql=> pg_restore
"pg_restore" is a command line utility program.
Use it from the system terminal or command prompt not from psql.
psql=>
psql=> select 1
psql-> pg_restore
"pg_restore" is a command-line utility program not a psql command. See
"help".
psql->
Wording advice would be welcome.
I'd be tempted to backpatch this, since it's one of the things I see users
confused by most often now - right up there with pg_hba.conf issues,
forgetting a semicolon in psql, etc.
--
Craig Ringer http://www.2ndQuadrant.com/
2ndQuadrant - PostgreSQL Solutions for the Enterprise
From 451b564fa8714ff4ba21725b183913d651b1c925 Mon Sep 17 00:00:00 2001
From: Craig Ringer <[email protected]>
Date: Fri, 6 Dec 2019 12:50:58 +0800
Subject: [PATCH] print help in psql when users try to run pg_dump etc
New users frequently attempt to run PostgreSQL's command line utilities
from the psql prompt. Detect this and emit a useful help message:
psql=> pg_restore
"pg_restore" is a command line utility program.
Use it from the system terminal or command prompt not from psql.
psql=>
Previously we'd just add the command to the buffer - and since the user
wouldn't generally follow it with a semicolon they'd see no response except a
prompt change:
psql=> pg_restore
psql->
---
src/bin/psql/mainloop.c | 48 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index f7b1b94599..2c65b7a862 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -353,6 +353,54 @@ MainLoop(FILE *source)
#else
puts(_("Use control-C to quit."));
#endif
+
+ /*
+ * New users tend to be confused about the command line utilities
+ * pg_dump, pg_restore, createdb, etc, and try to run them
+ * interatively in psql. Detect this and emit a suitable hint.
+ *
+ * We check for them even when the buffer is non-empty because
+ * users frequently try multiple commands without semicolons when
+ * trying to misuse psql as a command-line shell. Like with "help"
+ * etc, the text is still added to the buffer unless it's the
+ * first word on an empty buffer.
+ */
+ if (line[0] == 'p' || line[0] == 'c' || line[0] == 'd')
+ {
+ if (strncmp(line, "pg_restore", sizeof("pg_restore")) == 0
+ || strncmp(line, "pg_dump", sizeof("pg_dump")) == 0
+ || strncmp(line, "createdb", sizeof("createdb")) == 0
+ || strncmp(line, "dropdb", sizeof("dropdb")) == 0
+ || strncmp(line, "createuser", sizeof("createuser")) == 0
+ || strncmp(line, "dropuser", sizeof("dropuser")) == 0)
+ {
+ char cmdname[12];
+
+ strlcpy(&cmdname[0], line,
+ Min(strcspn(line, " \r\n") + 1, sizeof(cmdname)));
+ if (query_buf->len != 0)
+ {
+ /*
+ * Print a short hint but don't swallow the input if
+ * there's already something in the buffer.
+ */
+ printf(_("\"%s\" is a command-line utility program "
+ "not a psql command.\n"),
+ cmdname);
+ }
+ else
+ {
+ /* Swallow the input and emit more help */
+ printf(_("\"%s\" is a command line utility program.\n"
+ "Use it from the system terminal or command "
+ "prompt not from psql.\n"),
+ cmdname);
+ free(line);
+ fflush(stdout);
+ continue;
+ }
+ }
+ }
}
/* echo back if flag is set, unless interactive */
--
2.23.0