我的所有脚本都打开了errexit;也就是说,我运行set -o errexit
。但是,有时我想运行grep
之类的命令,但是即使命令失败也要继续执行我的脚本。
我该怎么做?也就是说,如何在不删除整个脚本的情况下将命令的退出代码转换为变量?
我可以关闭errexit,但我不愿意。
答案 0 :(得分:5)
如果失败的命令是“未经测试”,则errexit
只会导致脚本终止。在FreeBSD上按man sh
:
Exit immediately if any untested command fails in non-interactive
mode. The exit status of a command is considered to be explic-
itly tested if the command is part of the list used to control an
if, elif, while, or until; if the command is the left hand oper-
and of an ``&&'' or ``||'' operator; or if the command is a pipe-
line preceded by the ! keyword.
所以..如果你想使用这样的结构:
grep -q something /path/to/somefile
retval=$?
if [ $retval -eq 0 ]; then
do_something # found
else
do_something_else # not found
fi
你应该使用这样的结构:
if grep -q something /path/to/somefile; then
do_something # found
else
do_something_else # not found
fi
if
关键字的存在使得grep命令 已经过测试 ,因此不受errexit
的影响。这种方式可以减少打字。
当然,如果您真的需要变量中的退出值,那么没有什么可以阻止您使用$?
:
if grep -q something /path/to/somefile; then
do_something # found
else
unnecessary=$?
do_something $unnecessary # not found
fi
答案 1 :(得分:1)
以下是实现此目的的方法:您可以为某些代码行“关闭”for train in train_files:
with open(train) as f:
row = []
col = []
for index, line in enumerate(f):
record = line.rstrip().split(' ')
row = row+[index]*(len(record)-4)
col = col+record[4:]
row = np.array(row)
col = np.array(col)
data = np.array([1]*len(row))
mtx = sparse.coo_matrix((data, (row, col)), shape=(n_row, max_feature))
mmwrite(train+'trans',mtx)
,然后在您决定时再次启用它:
set -o errexit
另一种选择如下:
set +e #disables set -o errexit
grep -i something file.txt
rc="$?" #capturing the return code for last command
set -e #reenables set -o errexit
这将允许您捕获变量grep -i something file.txt || rc="$?"
上的返回码,而不会中断您的脚本。您甚至可以扩展最后一个选项来捕获并处理同一行上的返回代码,而不会有触发退出的风险:
rc
最后一位grep -i something file.txt || rc="$?" && echo rc="$?" > somefile.txt && command || :
将保证上面的行总是返回一个返回码= 0(真)。
答案 2 :(得分:1)
我能想到的最紧凑,最不重复的形式:
<command> && rc=$? || rc=$?
没有变量名称重复的表单 - rc=$(<command> && echo $? || echo $?)
- 具有表达式rvalue,但也会捕获<command>
1 的标准输出。因此,如果您“知道”<command>
没有正常输出,那么它是唯一安全的。
使用a && b || c
构造is safe here因为rc=$?
和$(echo $?)
永远不会失败。
1 当然,您可以通过摆弄文件描述符来解决这个问题,但这会使构造变得冗长且不方便作为标准