Linux 获取用于grep输出的空文件

Linux 获取用于grep输出的空文件,linux,bash,grep,scp,Linux,Bash,Grep,Scp,我正在脚本中运行此命令 while [ 1 ] do if [ -e $LOG ] then grep -A 5 -B 5 -f $PATTERNS $LOG >> $FOREMAIL break fi done $LOG文件是从另一台计算机上scp'ed的。所以只要它出现在当前目录中,while循环就会检测到它并执行grep。问题是,$FOREMAIL文件原来是空的。但是,如果我在脚本之外使用相同的文

我正在脚本中运行此命令

while [ 1 ]
do

    if [ -e $LOG ]
    then

            grep -A 5 -B 5 -f $PATTERNS $LOG  >> $FOREMAIL
            break
    fi

done
$LOG文件是从另一台计算机上scp'ed的。所以只要它出现在当前目录中,while循环就会检测到它并执行grep。问题是,$FOREMAIL文件原来是空的。但是,如果我在脚本之外使用相同的文件和参数作为独立命令运行这个grep,我可以看到它生成了一个输出


我不明白为什么这个命令在脚本中不生成o/p?

scp创建文件时,-e会立即触发,而文件中仍然没有数据,并且grep在一个空文件上操作。您需要等待文件传输完成

您可以通过传输到一个临时文件名来实现这一点,而不是从推送文件的机器上通过ssh运行mv

编辑:机器复制到日志文件的代码

scp $log 192.168.0.1:/logfiles/${log}.tmp
ssh 192.168.0.1 mv /logfiles/${log}.tmp /logfiles/${log}

可能是因为while[1]速度非常快,所以当文件开始复制时,在复制完成之前,它首先显示为一个空文件?根据文件的大小,在then循环中尝试睡眠延迟。在外部进程完成复制后,确定文件何时完成复制可能是一个单独的问题-例如,在谷歌上搜索诸如如何判断scp何时完成复制文件之类的内容时,会出现一系列链接,如:

最好使用:

if [ -f $LOG ]
而不是:

if [ -e $LOG ]
-f检查常规类型 -e检查任何文件
在您可以grep之前,您需要等待两件事情:1下载开始的文件开始存在,2下载完成没有人再打开该文件。我有一个脚本调用waitfor.sh,它执行以下操作:

#!/bin/bash

# waitfor.sh - wait for a file fully downloaded (via Firefox, scp, ...)
# Syntax:
#   waitfor.sh filename

FILENAME=$1 # Name of file to wait for
INTERVAL=10 # Wait interval of N seconds

# Wait for download started
while [ ! -f $FILENAME ] 
do
    sleep $INTERVAL
done

# Wait for download finished
while lsof $FILENAME
do
    sleep $INTERVAL
done
要使用它:

waitfor.sh $LOG
grep ...

下面是我最后做的:

scp$日志文件

然后

scp$SCPDONE空文件

并将if子句修改如下:

while [ 1 ]
do

    if [ -e $SCPDONE ]
    then

        grep -A 5 -B 5 -f $PATTERNS $LOG  >> $FOREMAIL
        break
    fi

done

如果您可以控制上载文件的进程,Rophuine在下面的回答中建议让该进程使用临时名称创建文件,然后将其移动到最终名称,这比休眠要好。脚本的输出是什么?而loop需要在里面睡一觉,$模式中有什么?我强烈建议用双引号括起来,因为一个典型的正则表达式中有无数的shell元字符。查看正在执行的确切命令;grep根本没有寻找你认为它在寻找的东西的可能性至少是中等的。