我正在尝试在多台远程计算机上拖尾日志文件并将输出转发到我的本地工作站.我想按Ctrl-C时关闭连接.
目前我有以下几乎按预期工作的功能.
function dogfight_tail() {
logfile=/var/log/server.log
pids=""
for box in 02 03; do
ssh server-$box tail -f $logfile | grep $1 &
pids="$pids $!"
done
trap 'kill -9 $pids' SIGINT
trap wait
}
连接关闭,我从尾部接收输出.但是,有一些缓冲正在进行,因为输出分批进行.
这是有趣的部分……
我可以在执行以下操作时看到相同的缓冲行为,并将“test”附加到远程机器上的文件/var/log/server.log 4-5次…
ssh server-01 "tail -f /var/log/server.log | grep test"
……并找到了两种禁用它的方法……
>向ssh添加-t标志.
ssh -t server-01 "tail -f /var/log/server.log | grep test"
>从远程命令中删除引用.
ssh server-01 tail -f /var/log/server.log | grep test
但是,这些方法都不适用于在上述多台机器上执行的功能.
我尝试过dsh,它在执行时具有相同的缓冲行为.
dsh -m server-01,server-02 -c "tail -f /var/log/server.log | grep test"
同样在这里,如果我删除引号,缓冲就会消失,一切正常.
dsh -m server-01,server-02 -c tail -f /var/log/server.log | grep test
还尝试了parallel-ssh,它与dsh完全相同.有人能解释一下这里发生了什么吗?
我该如何解决这个问题?如果可能的话,最好选择直接的ssh.
附:我不想使用multitail或类似的,因为我希望能够执行任意命令.
解决方法:
你看到的是Glibc提供的grep标准stdout缓冲区的效果.最好的解决方案是使用–line-buffered(GNU grep,我不确定其他实现可能支持它或类似的东西)来禁用它.
至于为什么这只会在某些情况下发生:
ssh server "tail -f /var/log/server.log | grep test"
在服务器上的引号中运行整个命令 – 因此grep等待填充其缓冲区.
ssh server tail -f /var/log/server.log | grep test
在通过ssh通道发送的输出尾部在本地计算机上运行grep.
这里的关键部分是,grep根据stdin是否为终端来调整其行为.运行ssh -t时,远程命令与控制终端一起运行,因此远程grep的行为与本地的一样.
标签:linux,ssh,tail
来源: https://codeday.me/bug/20190808/1623312.html