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 <cr...@2ndquadrant.com> 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