Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb0d8f2d

Browse files
committed
Add SHELL_ERROR and SHELL_EXIT_CODE magic variables to psql.
These are set after a \! command or a backtick substitution.SHELL_ERROR is just "true" for error (nonzero exit status) or "false"for success, while SHELL_EXIT_CODE records the actual exit statusfollowing standard shell/system(3) conventions.Corey Huinker, reviewed by Maxim Orlov and myselfDiscussion:https://postgr.es/m/CADkLM=cWao2x2f+UDw15W1JkVFr_bsxfstw=NGea7r9m4j-7rQ@mail.gmail.com
1 parent0f85db9 commitb0d8f2d

File tree

6 files changed

+88
-3
lines changed

6 files changed

+88
-3
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4267,6 +4267,34 @@ bar
42674267
</listitem>
42684268
</varlistentry>
42694269

4270+
<varlistentry id="app-psql-variables-shell-error">
4271+
<term><varname>SHELL_ERROR</varname></term>
4272+
<listitem>
4273+
<para>
4274+
<literal>true</literal> if the last shell command
4275+
failed, <literal>false</literal> if it succeeded.
4276+
This applies to shell commands invoked via the <literal>\!</literal>
4277+
meta-command or backquote (<literal>`</literal>) expansion.
4278+
See also <varname>SHELL_EXIT_CODE</varname>.
4279+
</para>
4280+
</listitem>
4281+
</varlistentry>
4282+
4283+
<varlistentry id="app-psql-variables-shell-exit-code">
4284+
<term><varname>SHELL_EXIT_CODE</varname></term>
4285+
<listitem>
4286+
<para>
4287+
The exit status returned by the last shell command.
4288+
0&ndash;127 represent program exit codes, 128&ndash;255
4289+
indicate termination by a signal, and -1 indicates failure
4290+
to launch a program or to collect its exit status.
4291+
This applies to shell commands invoked via the <literal>\!</literal>
4292+
meta-command or backquote (<literal>`</literal>) expansion.
4293+
See also <varname>SHELL_ERROR</varname>.
4294+
</para>
4295+
</listitem>
4296+
</varlistentry>
4297+
42704298
<varlistentry id="app-psql-variables-show-all-results">
42714299
<term><varname>SHOW_ALL_RESULTS</varname></term>
42724300
<listitem>

‎src/bin/psql/command.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5041,6 +5041,21 @@ do_shell(const char *command)
50415041
else
50425042
result=system(command);
50435043

5044+
if (result==0)
5045+
{
5046+
SetVariable(pset.vars,"SHELL_EXIT_CODE","0");
5047+
SetVariable(pset.vars,"SHELL_ERROR","false");
5048+
}
5049+
else
5050+
{
5051+
intexit_code=wait_result_to_exit_code(result);
5052+
charbuf[32];
5053+
5054+
snprintf(buf,sizeof(buf),"%d",exit_code);
5055+
SetVariable(pset.vars,"SHELL_EXIT_CODE",buf);
5056+
SetVariable(pset.vars,"SHELL_ERROR","true");
5057+
}
5058+
50445059
if (result==127||result==-1)
50455060
{
50465061
pg_log_error("\\!: failed");

‎src/bin/psql/help.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ helpVariables(unsigned short int pager)
451451
HELP0(" SERVER_VERSION_NAME\n"
452452
" SERVER_VERSION_NUM\n"
453453
" server's version (in short string or numeric format)\n");
454+
HELP0(" SHELL_ERROR\n"
455+
" true if the last shell command failed, false if it succeeded\n");
456+
HELP0(" SHELL_EXIT_CODE\n"
457+
" exit status of the last shell command\n");
454458
HELP0(" SHOW_ALL_RESULTS\n"
455459
" show all results of a combined query (\\;) instead of only the last\n");
456460
HELP0(" SHOW_CONTEXT\n"

‎src/bin/psql/psqlscanslash.l

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "postgres_fe.h"
2020

2121
#include "psqlscanslash.h"
22+
#include "settings.h"
23+
2224
#include "common/logging.h"
2325
#include "fe_utils/conditional.h"
2426

@@ -772,6 +774,7 @@ evaluate_backtick(PsqlScanState state)
772774
PQExpBufferData cmd_output;
773775
FILE *fd;
774776
boolerror =false;
777+
intexit_code =0;
775778
charbuf[512];
776779
size_tresult;
777780

@@ -783,6 +786,7 @@ evaluate_backtick(PsqlScanState state)
783786
{
784787
pg_log_error("%s: %m", cmd);
785788
error =true;
789+
exit_code = -1;
786790
}
787791

788792
if (!error)
@@ -800,10 +804,19 @@ evaluate_backtick(PsqlScanState state)
800804
}while (!feof(fd));
801805
}
802806

803-
if (fd &&pclose(fd) == -1)
807+
if (fd)
804808
{
805-
pg_log_error("%s: %m", cmd);
806-
error =true;
809+
/*
810+
* Although pclose's result always sets SHELL_EXIT_CODE, we
811+
* historically have abandoned the backtick substitution only if it
812+
* returns -1.
813+
*/
814+
exit_code =pclose(fd);
815+
if (exit_code == -1)
816+
{
817+
pg_log_error("%s: %m", cmd);
818+
error =true;
819+
}
807820
}
808821

809822
if (PQExpBufferDataBroken(cmd_output))
@@ -826,5 +839,10 @@ evaluate_backtick(PsqlScanState state)
826839
appendBinaryPQExpBuffer(output_buf, cmd_output.data, cmd_output.len);
827840
}
828841

842+
/* And finally, set the shell error variables */
843+
snprintf(buf,sizeof(buf),"%d",wait_result_to_exit_code(exit_code));
844+
SetVariable(pset.vars,"SHELL_EXIT_CODE", buf);
845+
SetVariable(pset.vars,"SHELL_ERROR", (exit_code ==0) ?"false" :"true");
846+
829847
termPQExpBuffer(&cmd_output);
830848
}

‎src/common/wait_error.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,22 @@ wait_result_is_any_signal(int exit_status, bool include_command_not_found)
127127
return true;
128128
return false;
129129
}
130+
131+
/*
132+
* Return the shell exit code (normally 0 to 255) that corresponds to the
133+
* given wait status. The argument is a wait status as returned by wait(2)
134+
* or waitpid(2), which also applies to pclose(3) and system(3). To support
135+
* the latter two cases, we pass through "-1" unchanged.
136+
*/
137+
int
138+
wait_result_to_exit_code(intexit_status)
139+
{
140+
if (exit_status==-1)
141+
return-1;/* failure of pclose() or system() */
142+
if (WIFEXITED(exit_status))
143+
returnWEXITSTATUS(exit_status);
144+
if (WIFSIGNALED(exit_status))
145+
return128+WTERMSIG(exit_status);
146+
/* On many systems, this is unreachable */
147+
return-1;
148+
}

‎src/include/port.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ extern char *escape_single_quotes_ascii(const char *src);
495495
externchar*wait_result_to_str(intexitstatus);
496496
externboolwait_result_is_signal(intexit_status,intsignum);
497497
externboolwait_result_is_any_signal(intexit_status,boolinclude_command_not_found);
498+
externintwait_result_to_exit_code(intexit_status);
498499

499500
/*
500501
* Interfaces that we assume all Unix system have. We retain individual macros

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp