grep $? -ne 0 中断脚本

grep $? -ne 0 中断脚本

我有一个执行所有命令直到到达if语句的脚本:

脚本:

#!/bin/bash

######VARIABLES#######
#grep return value
gret=$?

######LOGIC#######
cd /home/logs
echo "Enter filename: "
read filenamex
echo "filename : ${filenamex}"
grep ${filenamex} log.dat | grep "End receiving ftp file:"
echo $?

if [ {gret} -ne 0 ]; then
   echo "{filenamex} cannot be found in the recent logs. We will now check the old logs."
   sleep 3
   grep ${filenamex} log.dat* | grep "End receiving ftp file:"
fi

任何人都可以帮我执行脚本,以便如果我无法获得grep所需的值,脚本将执行该if语句吗?

答案1

$您的代码的主要问题是测试中缺少({gret}应该是${gret},或者更好,"$gret"),并且您从未将退出状态分配grep给变量(如果您直接gret使用 with ,则实际上没有必要,如下所述) 。grepif

if您可以直接在语句中使用命令的退出状态。下面的代码还需要一个文件名作为命令行参数,而不是交互式地询问它。

#!/bin/sh

if [ -z "$1" ]; then
    echo 'Expected to get a filename as argument'
    exit 1
fi >&2

if ! grep -Fe "$1" /home/logs/log.dat | grep -F 'End receiving ftp file:'
then
    echo 'Checking older logs...' >&2
    grep -Fe "$1" /home/logs/log.dat?* | grep -F 'End receiving ftp file:'
fi

上面的代码使用-Fwithgrep来避免将模式解释为正则表达式,并-e避免将模式误认为是一组选项(如果它以破折号开头)。如果要将给定字符串用作正则表达式,请从每个管道中的-F第一个字符串中删除。grepgrep

文件名通配模式/home/logs/log.dat?*匹配以/home/logs开头的名称log.dat,而不匹配实际名称log.dat本身。它通过在名称的初始前缀后至少需要一个额外字符来实现这一点log.dat

我把脚本变成了sh脚本,因为它没有使用bash特定的功能。


重构上面的代码以避免重复几乎相同的grep管道两次:

#!/bin/sh

if [ -z "$1" ]; then
    echo 'Expected to get a filename as argument'
    exit 1
fi >&2

do_grep () {
    pattern=$1; shift

    grep -Fe "$pattern" -- "$@" |
        grep -F 'End receiving ftp file:'
}

if ! do_grep "$1" /home/logs/log.dat; then
    echo 'Checking older logs...' >&2
    do_grep "$1" /home/logs/log.dat?*
fi

相关内容