我正在编写一个脚本来读取输入文件,其中包含大约1000行主机信息。脚本ssh到每个主机,cd到远程主机日志目录并获取最新每日日志文件。然后我在本地重定向cat日志文件以进行一些模式匹配和统计。
我的程序的简化结构是while循环,如下所示:
while read host
do
ssh -n name@$host "cd TO LOG DIR AND cat THE LATEST LOGFILE" | matchPattern
done << EOA
$(awk -F, '{print &7}' $FILEIN)
EOA
其中matchPattern是匹配模式和统计数据的函数。
现在我有两个问题:
1)如何远程查找最新日常日志文件? 最新的日志文件名与xxxx2012-05-02.log匹配并且是最新创建的,是否可以远程执行ls并找到与xxxx2012-05-02.log文件名匹配的文件?(I可以在本地执行此操作,但在将其附加到ssh命令时会卡住)另一种我想出的方法是
cat 'ls -t | head -1' or
cat $(ls -t | head -1)
但是,如果我将此附加到ssh,它将列出我本地最新创建的文件名,我们可以将其设置为远程变量,以便cat找到正确的文件吗?
2)由于有近1000个主机,我想知道我可以并行执行此操作(例如一次执行20个ssh并在前20个完成后执行下一个20个),附加&amp;每个ssh似乎都不足以实现它。
任何想法都将不胜感激!
跟进: 大家好,我终于找到了一个蹩脚的方法来解决第一个问题:
ssh -n name@$host "cd $logDir; cat *$logName" | matchPattern
$ logName是“今天的date.log”(2012-05-02.log)。问题是我只能在双引号中使用本地变量。由于我的日志文件以2012-05-02.log结尾,并且没有其他文件以此后缀结尾,我只是在远程计算机上盲目地cat *2012-05-02.log
,它将为我捕获所需的文件。
答案 0 :(得分:1)
关于第二个问题,看一下并行分布式shell:
答案 1 :(得分:1)
关于第一个问题,
ssh -n name@$host 'cat $(ls -t /path/to/log/dir/*.log | head -n 1)'
应该有效。注意远程命令周围的单引号。
对于第二个问题,将所有ssh | matchPattern | analyse
内容包装到自己的函数中,然后通过
outstanding=0
while read host
do
sshMatchPatternStuff &
outstanding=$((outstanding + 1))
if [ $outstanding -ge 20 ] ; then
wait
outstanding=$((outstanding - 1))
fi
done << EOA
$(awk -F, '{print &7}' $FILEIN)
EOA
while [ $outstanding -gt 0 ] ; do
wait
outstanding=$((outstanding - 1))
done
(我假设你正在使用bash
。)
最好将ssh | matchPattern | analyse
内容分成自己的脚本,然后使用xargs
的并行变体来调用它。
答案 2 :(得分:0)
如果你安装了GNU Parallel http://www.gnu.org/software/parallel/,你可以这样做:
parallel -j0 --nonall --slf <(awk -F, '{print $7}' servers.txt) 'cd logdir; cat `ls -t | head -1` | grep pattern'
这样您就可以在远程服务器上完成匹配。如果您希望传输完整的日志文件并在本地进行匹配,只需将grep移到外面:
parallel -j0 --nonall --slf <(awk -F, '{print $7}' servers.txt) 'cd logdir; cat `ls -t | head -1`' | grep pattern
您可以通过以下方式安装GNU Parallel:
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
观看GNU Parallel的介绍视频了解详情: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1