在shell脚本中使用unix cat和zcat组合文件的问题

时间:2010-09-18 15:23:21

标签: shell unix

我的shell脚本有问题。我基本上是尝试使用unix(zcat, cat)命令从(2)文件创建一个新的日志文件

FileA = gzipped logfile (.gz)
FileB = non-gzipped log file (.log)

FileC = new file from FileA:FileB

我的问题在于FileC

例如: FileA具有来自Aug19-Sept3的时间戳数据 FileB具有来自Sept4-Sept17的时间戳数据 FileC包含来自两个文件= Aug19-Sept3:Sept4-Sept17

的内容

问题: 如果我在服务器上手动运行命令,文件看起来很好,因为我希望FileC有来自Aug19-Sept17的时间戳数据 但是,如果以编程方式使用shell脚本完成,当我将其远程复制时,本地副本将如下所示: FileC = Aug19-Sept17:Aug19-Sept2

所以我的问题是为什么这会以编程方式发生? 是否有更好的方法将这两个日志组合/缝合在一起创建另一个日志?

这是我的shell脚本:

#!/bin/bash
if [ $# != 1 ]; then
    echo "Usage: getlogs.sh <remote-host>" 2>&1
    exit 1
fi

#Declare variables
STAMP=`date '+%Y%m%d-%H:%M'`
REMOTE_MYCNF=/var/log/mysoft/mysoft.log
REMOTE_GZ=/var/log/mysoft/mysoft.log.1.gz
REMOTE_DIR=/var/log/mysoft/
BACKUP_DIR=/home/dev/logs/
NEWLOG="foo-temp.log"

#Copy file over
echo "START..." 2>&1
test -f $BACKUP_DIR$1.mysoft.log
if [ $? = 0 ]; then
   echo "Local log file $BACKUP_DIR$1.mysoft.log exists, clean up for new copy..." 2>&1
   /bin/rm $BACKUP_DIR$1.mysoft.log
   else
        echo "File does not exist, getting a new copy..." 2>&1
fi

echo "Checking remotely in $1 for logfile $REMOTE_MYCNF $STAMP" 2>&1
if [ ! -f $REMOTE_MYCNF ]; then
   echo "File exists remotely, creating new logfile and copy here...." 2>&1
   ssh $1 "zcat $REMOTE_GZ >> $REMOTE_DIR$NEWLOG"
   ssh $1 "cat $REMOTE_MYCNF >> $REMOTE_DIR$NEWLOG"
   /usr/bin/scp $1:$REMOTE_DIR$NEWLOG $BACKUP_DIR$1.mysoft.log
   echo "end remote copy" 2>&1
   echo "Cleaning up remote files" 2>&1
   ssh $1 "rm $REMOTE_DIR$NEWLOG"
   exit 0
   else
        echo "Unable to get file" 2>&1
        exit 0
fi

4 个答案:

答案 0 :(得分:3)

也许cat可能在zcat完成之前开始。但是,如果是这种情况,我会感到惊讶。

试试这个:

ssh $1 "zcat ... >> ...; cat ... >> ..."

ssh $1 "zcat ... >> ..."
sleep 5
ssh $1 "cat ... >> ..."

ssh $1 "zcat -f file1 file2 >> ..."   # let zcat do both files

答案 1 :(得分:1)

我无法立即猜出错误是什么,但您是否尝试过简化shell脚本?也就是说,从这开始:

#!/bin/sh
STAMP=`date '+%Y%m%d-%H:%M'`
REMOTE_MYCNF=/var/log/mysoft/mysoft.log
REMOTE_GZ=/var/log/mysoft/mysoft.log.1.gz
REMOTE_DIR=/var/log/mysoft/
BACKUP_DIR=/home/dev/logs/
NEWLOG="foo-temp.log"
ssh $1 "zcat $REMOTE_GZ >> $REMOTE_DIR$NEWLOG"
ssh $1 "cat $REMOTE_MYCNF >> $REMOTE_DIR$NEWLOG"

然后从这里建立起来。这至少可以让你解决问题。

答案 2 :(得分:1)

您根本不需要创建远程临时文件。摆脱多个ssh命令,scp和清理ssh,然后尝试这样做:

ssh $1 "zcat $REMOTE_GZ; cat $REMOTE_MYCNF;" > $BACKUP_DIR$1.mysoft.log

zcat和cat会将数据写入他们的stdout,该stdout附加到ssh的stdout,我们将其重定向到文件。

我“保证”zcat在cat开始之前写入所有数据并退出,给出所需的顺序。 “保证”是引号,因为其他解决方案应该有效,而不是报告。

答案 3 :(得分:0)

似乎临时文件正在被重用,删除或截断它:

# Always using the same log for new log.
NEWLOG="foo-temp.log"
# Use a new log truncate '>' the old one
ssh $1 "zcat $REMOTE_GZ > $REMOTE_DIR$NEWLOG"
# This time, append '>>' to new log
ssh $1 "cat $REMOTE_MYCNF >> $REMOTE_DIR$NEWLOG"