2

我正在编写一个 shell 脚本,它应该监视一些日志文件并将输出重定向到一个文件。我正在使用tail -f命令这样做,但它似乎不起作用。这是我的脚本。

#!/bin/bash

ssh -q sc-2 tail -f /home/logs/oam-2.log > /root/logs/file.log &

echo "press return to strop the trace"

read A

kill `ps -ef| grep tail| grep sc-2| grep "\.log"| awk '{print $2}'` 2>/dev/null &

当我运行脚本时,file.log 中只打印了 5 行

4

1 回答 1

2

尽管您通过 将ssh进程发送到后台&,但它的文件描述符仍然“附加”到您的终端。一个示范:

# Terminal 1
$ ssh $host sleep 600 &
[3] 14340

# Terminal 2
$ ls -l /proc/14340/fd
lrwx------ 1 iscfrc iscfrc 64 Oct  3 10:30 0 -> /dev/pts/1
lrwx------ 1 iscfrc iscfrc 64 Oct  3 10:30 1 -> /dev/pts/1
lrwx------ 1 iscfrc iscfrc 64 Oct  3 10:30 2 -> /dev/pts/1
lr-x------ 1 iscfrc iscfrc 64 Oct  3 10:30 3 -> socket:[125941180]
lrwx------ 1 iscfrc iscfrc 64 Oct  3 10:31 4 -> /dev/pts/1
lrwx------ 1 iscfrc iscfrc 64 Oct  3 10:31 5 -> /dev/pts/1
lrwx------ 1 iscfrc iscfrc 64 Oct  3 10:31 6 -> /dev/pts/1

请注意所有 FD(减去 TCP 套接字)如何附加到/dev/pts/1.

那么当您的脚本运行时会发生什么ssh,将其置于后台,但该ssh进程继续轮询终端以获取输入?

# Terminal 2
$ sudo strace -p 14340
Process 14340 attached - interrupt to quit
select(7, [3 4], [], NULL, NULL

# Terminal 1
$ read

# Terminal 2, output
select(7, [3 4], [], NULL, NULL)        = 1 (in [4])
read(4, 0xbff1dbbc, 16384)              = ? ERESTARTSYS (To be restarted)
--- SIGTTIN (Stopped (tty input)) @ 0 (0) ---
--- SIGTTIN (Stopped (tty input)) @ 0 (0) ---
# (infinite loop of the previous three lines)

尝试read()从文件描述符输入时会出现恐慌4,您可以在上面看到终端。( 4 -> /dev/pts/1)

解决办法是断开ssh终端的输入;我建议使用nohup

nohup ssh -q sc-2 tail -f /home/logs/oam-2.log > /root/logs/file.log &

供考虑的其他建议:

  1. -T参数添加到您的ssh命令以禁用远程主机上的 TTY 分配。由于您不需要与tail命令交互,因此不需要 TTY。
  2. ssh命令的 PID 存储到变量 via$!中,以节省您需要解析ps.
  3. 为了更加简朴,您可以echo通过使用read'-p选项来节省自己的时间。(p用于提示

结合以上所有:

nohup ssh -qT sc-2 tail -f /home/logs/oam-2.log >/root/logs/file.log &
sshpid=$!
read -p $'press return to stop the trace\n'
kill $sshpid

我测试了上述内容(填写了我自己的主机/文件路径),它运行了超过 10 分钟而没有停止。

于 2013-10-03T18:06:51.873 回答