采用以下bash脚本:
ls: cannot access /sdfg: No such file or directory
Command failed: 0
输出将是:
<VirtualHost *:80>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyRequests Off
<Proxy http://localhost:8080/*>
Order deny,allow
Allow from all
</Proxy>
</VirtualHost>
失败的ls命令实际上返回2,if语句捕获了这个,并且echos命令失败,但为什么$?得到更新到零?看起来if / then行被视为新命令。
答案 0 :(得分:2)
[
实际上是一个二进制文件,而不只是一些标点符号:
$ ls -l /usr/bin/[
-rwxr-xr-x 1 root root 51920 Feb 18 07:37 /usr/bin/[
$ /usr/bin/[ --version
[ (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
并且在某些系统上可能是test
的符号链接。
所以这里
if [ $? -gt 0 ]
$?
是您ls
来电的结果,但此处
echo "Command failed: $?"
$?
是在前一行执行[
的结果。
如果您想多次从命令中测试$?
,您必须将其填入temp var:
ls blahblah
temp=$?
if [ $temp ... ]
if [ $temp ... ]
答案 1 :(得分:2)
您应该很少需要明确地检查$?
,因为这样做的目的是if
(以及其他条件内置函数,如while
)。写这个的正确方法是
if ls /sdfg; then
echo "Command succeeded: $?"
else
echo "Command failed: $?"
fi
注意失败案例现在是else
分支。 (如果您不特别关心保留失败退出代码,可以使用if ! ls
...并将成功分支保留在else
中,但您的问题似乎是专门关于保留它,!
的否定不会。)
答案 2 :(得分:2)
如果您要重复使用,请在测试命令后立即收集返回值 :
File "/home/username/.virtualenvs/venv/local/lib/python2.7/site-packages/requests/adapters.py", line 467, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: SOCKSHTTPSConnectionPool(host='api-server.com', port=443): Max retries exceeded with url: /auth (Caused by NewConnectionError('<requests.packages.urllib3.contrib.socks.SOCKSHTTPSConnection object at 0x95c7ccc>: Failed to establish a new connection: SOCKS5 proxy server sent invalid data',))
但是,最佳做法是直接对命令的退出状态进行操作,而无需完全引用#!/bin/bash
# best-practice: collect *on the same line*, so any logging added in the future doesn't
# ...change your exit status.
ls /sdfg; retval=$?
if [ $retval -gt 0 ]; then
echo "Command failed: $retval" #
else
echo "Command succeeded: $retval"
fi
:
$?