批处理循环中的 PSQL 错误级别
PSQL Error Level in Batch For Loop
我正在尝试从批处理文件中 运行 postgres 查询。但是,到目前为止,我无法检测到命令何时失败。以下是我迄今为止尝试过的方法:
@FOR /F %%A IN ('PSQL -U userName -d dbName -t -c "SELECT * FROM nonExistantTable" 2^>^&1') DO @(
ECHO !ERRORLEVEL!
)
我也试过以下方法:
1) 在 sql 命令之前添加 "CALL" (CALL PSQL -U ...
)
2) 将“-v ON_ERROR_STOP=1”添加到 sql 命令中,无论是否使用 "CALL" 命令 (PSQL -U ... -v ON_ERROR_STOP=1
)
但是,ERRORLEVEL 的值始终为零。有谁知道如何使用批处理检测 PSQL 调用中的错误?具体来说,我收到的错误是 table 不存在。谢谢
for /f
在单独的 cmd
实例中执行命令,并且此实例中的 errorlevel
不会导出到 do
子句中的代码。
在纯批处理中更好的处理方式是:
- 将程序的输出发送到临时文件
- 检查错误级别
- 如果没有错误处理文件输出
- 无论如何删除末尾的临时文件
类似
set "tempFile=%temp%\%~n0.%random%%random%%random%.tmp"
> "%tempFile%" 2>&1 (
PSQL -U userName -d dbName -t -c "SELECT * FROM nonExistantTable"
)
if not errorlevel 1 (
for /f "usebackq delims=" %%g in ("%tempFile%") do (
echo %%g
)
) else (
echo ERRORLEVEL: %errorlevel%
)
del /q "%tempFile%"
@MCND的回答可以概括为:
1) 运行 命令正常,将 stdout 重定向到临时文件
2)根据ERRORLEVEL
处理文件内容
基于这个答案,我想出了一个解决方案,它可以用更少的代码满足我的特定需求。我的情况有点特殊,因为 PSQL 命令恰好执行以下操作之一:
1) 将结果写入标准输出,并且return归零
2) 将错误写入 stderr,并且 returns 非零
在案例 #1 中,我希望我的批处理文件打印结果 return 0。在案例 #2 中,我想执行一些自定义逻辑,打印错误,并且 return非零。对于这个逻辑,我发现以下方法效果更好:
:: Get a temporary file name
@SETLOCAL
@SET TEMP_OUT="%TEMP%\myScriptError.log"
:: Create the command that will be executed
@SET DB_SELECT=SELECT * FROM nonExistantTable
@SET DB_COMMAND=PSQL -U userName -d dbName -t -c "%DB_SELECT%"
:: Run the command
@FOR /F %%A IN ('%DB_COMMAND% 2^>%TEMP_OUT%') DO @(
REM This code only runs if there are no errors
SET EXIT_CODE=0
GOTO :CLEANUP
)
:: Uh-oh, there was an error. Print it to stderr, and set the exit code.
@MORE %TEMP_OUT% 1>&2
@SET EXIT_CODE=1
...
:: Clean up the temp file and return the result
:CLEANUP
@DEL /F /Q %TEMP_OUT%
@ENDLOCAL & EXIT /B %EXIT_CODE%
我正在尝试从批处理文件中 运行 postgres 查询。但是,到目前为止,我无法检测到命令何时失败。以下是我迄今为止尝试过的方法:
@FOR /F %%A IN ('PSQL -U userName -d dbName -t -c "SELECT * FROM nonExistantTable" 2^>^&1') DO @(
ECHO !ERRORLEVEL!
)
我也试过以下方法:
1) 在 sql 命令之前添加 "CALL" (CALL PSQL -U ...
)
2) 将“-v ON_ERROR_STOP=1”添加到 sql 命令中,无论是否使用 "CALL" 命令 (PSQL -U ... -v ON_ERROR_STOP=1
)
但是,ERRORLEVEL 的值始终为零。有谁知道如何使用批处理检测 PSQL 调用中的错误?具体来说,我收到的错误是 table 不存在。谢谢
for /f
在单独的 cmd
实例中执行命令,并且此实例中的 errorlevel
不会导出到 do
子句中的代码。
在纯批处理中更好的处理方式是:
- 将程序的输出发送到临时文件
- 检查错误级别
- 如果没有错误处理文件输出
- 无论如何删除末尾的临时文件
类似
set "tempFile=%temp%\%~n0.%random%%random%%random%.tmp"
> "%tempFile%" 2>&1 (
PSQL -U userName -d dbName -t -c "SELECT * FROM nonExistantTable"
)
if not errorlevel 1 (
for /f "usebackq delims=" %%g in ("%tempFile%") do (
echo %%g
)
) else (
echo ERRORLEVEL: %errorlevel%
)
del /q "%tempFile%"
@MCND的回答可以概括为:
1) 运行 命令正常,将 stdout 重定向到临时文件
2)根据ERRORLEVEL
基于这个答案,我想出了一个解决方案,它可以用更少的代码满足我的特定需求。我的情况有点特殊,因为 PSQL 命令恰好执行以下操作之一:
1) 将结果写入标准输出,并且return归零
2) 将错误写入 stderr,并且 returns 非零
在案例 #1 中,我希望我的批处理文件打印结果 return 0。在案例 #2 中,我想执行一些自定义逻辑,打印错误,并且 return非零。对于这个逻辑,我发现以下方法效果更好:
:: Get a temporary file name
@SETLOCAL
@SET TEMP_OUT="%TEMP%\myScriptError.log"
:: Create the command that will be executed
@SET DB_SELECT=SELECT * FROM nonExistantTable
@SET DB_COMMAND=PSQL -U userName -d dbName -t -c "%DB_SELECT%"
:: Run the command
@FOR /F %%A IN ('%DB_COMMAND% 2^>%TEMP_OUT%') DO @(
REM This code only runs if there are no errors
SET EXIT_CODE=0
GOTO :CLEANUP
)
:: Uh-oh, there was an error. Print it to stderr, and set the exit code.
@MORE %TEMP_OUT% 1>&2
@SET EXIT_CODE=1
...
:: Clean up the temp file and return the result
:CLEANUP
@DEL /F /Q %TEMP_OUT%
@ENDLOCAL & EXIT /B %EXIT_CODE%