我有一个执行所有命令直到到达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 ,则实际上没有必要,如下所述) 。grep
if
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
上面的代码使用-F
withgrep
来避免将模式解释为正则表达式,并-e
避免将模式误认为是一组选项(如果它以破折号开头)。如果要将给定字符串用作正则表达式,请从每个管道中的-F
第一个字符串中删除。grep
grep
文件名通配模式/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