检查命令是否成功使shell脚本很长

时间:2018-01-04 16:56:44

标签: bash shell

我正在编写一个shell安装脚本
在每个命令之后我需要检查命令是否成功 - 我必须通知用户失败的原因 如果出现故障 - 安装无法继续,目前在我添加的每个命令之后

if [ $? -eq 0 ]; then  

但是这为shell脚本的每个命令增加了6行 有没有办法缩短这个检查?

样品:

do some command
if [ $? -eq 0 ]; then
    echo notify user OK
else
    echo notify user FAIL
    return -1
fi
do some command
if [ $? -eq 0 ]; then
    echo notify user OK
else
    echo notify user FAIL
    return -1
fi

4 个答案:

答案 0 :(得分:4)

首先,检查命令是否有效的惯用方法直接在if语句中。

if command; then
    echo notify user OK >&2
else
    echo notify user FAIL >&2
    return -1
fi

(良好做法:使用>&2将消息发送给stderr。)

有几种方法可以简化这一点。

编写功能

就像在其他编程语言中一样,可以将通用逻辑转移到共享函数中。

check() {
    local command=("$@")

    if "${command[@]}"; then
        echo notify user OK >&2
    else
        echo notify user FAIL >&2
        exit 1
    fi
}

check command1
check command2
check command3

不要打印任何内容

在惯用shell脚本中,成功的命令不会打印任何内容。什么都不打印意味着UNIX的成功。此外,任何失败的良好命令都会打印错误消息,因此您不需要添加错误消息。

利用这两个事实,只要命令失败,就可以使用|| exit退出。您可以将||视为"否则"。

command1 || exit
command2 || exit
command3 || exit

使用-e

或者,您可以启用-e shell标志,以便在命令失败时退出shell。然后你根本不需要任何东西。

#!/bin/bash -e

command1
command2
command3

不要打印任何内容

如果您确实需要错误消息,但没有成功消息,则die()功能很受欢迎。

die() {
    local message=$1

    echo "$message" >&2
    exit 1
}

command1 || die 'command1 failed'
command2 || die 'command2 failed'
command3 || die 'command3 failed'

答案 1 :(得分:3)

这是一个代码反模式。你想要

if do some command; then
    echo notify user OK
else
    echo notify user fail
    exit 255  # exit code must be unsigned short
fi

脚本顶部的命令set -e将强制shell发出故障信号并在任何命令失败时退出脚本。这有一些不明显的复杂情况,但实际上可能就是你想要的。

回到前面的主题,一个共同的风格是

do some command && echo notify user OK || die 255 Notify user fail

die的定义是easily googlable,也可能激发您探索将成功场景重构为函数的方法,以便您可以执行类似

的操作
guard "enable the frobnitz" do some command

可能guard定义为

guard () {
    local what=$1
    shift
    if "$@"; then
        echo "$what succeeded" >&2
    else
        rc=$?
        echo "$what failed" >&2
        exit $rc
    fi
}

另请注意这有多重要的改进;我们保留原始故障退出代码,并将所有诊断打印到标准错误。实际上,前面的例子也应该至少适当地做后者。

答案 2 :(得分:2)

将此添加到脚本的开头。如果任何命令返回非零状态,它将使shell停止脚本。

set -e

问候!

答案 3 :(得分:1)

我猜你可以在一个函数中移动检查逻辑,如:

checkLastCommand() {
     if [ $? -eq 0 ]; then
          echo notify user OK
     else 
          echo notify user FAIL
          exit -1 
     fi
 }
 do some command
 checkLastCommand
 do some command
 checkLastCommand