Grep问题与shell脚本中的if语句有关

PJ *_*aki 0 bash shell grep if-statement tail

我在shell脚本if语句中有tail&问题grep。如果我tail -5 mylog.log | grep -c "Transferred: 0"在shell中运行,它将按预期运行,但是在此shell脚本中,如果if语句:

# Parse log for results
if [ tail -1 "$LOGFILE" | grep -c "Failed" ] ; then
        RESULT=$(tail -1 "$LOGFILE")
elif [ tail -5 "$LOGFILE" | grep -c "Transferred:            0" ] ; then
        RESULT=""
else
        RESULT=$(tail -5 "$LOGFILE")
fi
Run Code Online (Sandbox Code Playgroud)

我懂了

... [: missing `]'
grep: ]: No such file or directory
Run Code Online (Sandbox Code Playgroud)

对于两个grep行。

显然,关闭]被视为grep的一部分(因此丢失),但是我使用的是正确的空格,所以我不知道发生了什么?我在这里做错了什么?

谢谢,PJ

Cha*_*ffy 5

立即发布/立即修复

取出支架。

if tail -1 "$logfile" | grep -q "Failed" ; then
Run Code Online (Sandbox Code Playgroud)

[不是if语法的一部分。而是,它是名为命令的同义词test(通常既可以作为内置的shell使用,也可以作为外部二进制文件(如/bin/test或/usr/bin/test)使用)。

因此,您的原始代码正在运行[ tail -1 "$logfile",并将其结果传递给grep -q "Failed" ]。第一个[失败是因为它没有看到结尾]-当以该名称而不是名称来调用时是强制性的test-并且还因为它的参数不是它知道如何解析的测试。第二个grep不知道]它是用管道传递的意思,试图用该名称查找文件。


其他注意事项

尝试tail尽可能少地运行外部命令(例如)。启动成本非常高。

考虑以下内容,该内容tail仅运行一次:

#!/bin/bash
#      ^^^^- IMPORTANT: bash, not /bin/sh

last_5_lines="$(tail -5 "$logfile")"
last_line="${last_5_lines##*$'\n'}"
if [[ $last_line = *Failed* ]]; then
  result=$last_line
elif [[ $last_5_lines =~ 'Transferred:'[[:space:]]+'0' ]]; then
  result=''
else
  result=$last_5_lines
fi
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,以解释所有小写变量-参见http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html;全大写名称用于对外壳程序或操作系统有意义的变量,而名称中至少具有一个小写字符的变量保留供应用程序使用。那只是用于环境变量的黑色字母POSIX,但是由于设置常规的shell变量将覆盖任何名称相同的环境变量,因此如果您想避免冲突,则约定也必须适用于它们。 (2认同)