使用屏幕监视非交互式脚本(或其他解决方案)

使用屏幕监视非交互式脚本(或其他解决方案)

我有一些自主脚本,它们通过 ssh 在远程机器上运行命令。这些脚本依赖于获取 stdout、stderr 和每个命令运行的返回代码。我希望能够监控每个目标机器上的脚本进度,以便查看是否有问题挂起,并在必要时进行干预。

我最初的想法是让脚本在屏幕会话中运行命令,这样监控人员就可以简单地使用 附加到会话中screen -x。但是,由于屏幕是一个交互式程序,因此很难从脚本中做到这一点。我可以使用 向屏幕会话发送命令screen -S session -X stuff "command^M",但这样我就得不到我需要的输出和返回代码。

我的第二个想法是将整个会话script /path/to/log记录~/.bash_profile到一个文件中。然后监控人员只需跟踪日志文件即可。然而,这并不能提供我想要的交互性。

关于如何解决这个问题有什么想法吗?

答案1

我使用 php 作为 shell 脚本来管理我的 Minecraft 服务器。我使用服务器日志来获取回复。这是我用来列出谁在线的代码。我用它来tail获取最后几行并解析它们的时间,以确保响应是在我发送命令之后。

#!/usr/bin/php
<?php
function send_cmd( $command )
{
        exec('screen -S minecraft -X stuff "`printf "\\r' . $command . '\\r"`"');
}

function who()
{
        if (!is_running())
        {
                echo 'Server is not running.' . CRLF;
                return 4;
        }

        // Get the current time and send the command
        $before = time() - 1;
        send_cmd('list');

        // Wait for the server to provide a response
        while(time() < $before + 5) {
                sleep(0.25);
                $result = exec('tail ' . __DIR__ . '/server.log | grep "\[INFO\] Connected players"');
                $stamp = strtotime(substr($result, 0, 19));
                if ($before <= $stamp)
                        break;
                unset($result);
        }

        if (isset($result))
        {
                echo $result . CRLF;
                echo 'Server responded in ' . ($stamp - $before) . ' seconds.' . CRLF;
                return 0;
        }
        else
        {
                echo 'Server did not respond.' . CRLF;
                return 4;
        }
}

答案2

大量的人际交往......我建议:

  1. 部署Check_MK并设置其日志监控
  2. 将脚本输出传送到日志文件并让 Check_MK 监视错误

在这种情况下,只有出现问题时,人员才会收到警报。他们有机会通过 Web 界面查看日志消息,确认消息,以便团队中的其他人知道事情正在处理中,并根据问题的性质决定何时采取行动。

答案3

我建议使用“nohup”——这会将 stdout 输出到 nohup.out。您可以使用 nohup 来 bg 脚本并安全注销,它将继续运行。查看 man nohup 了解更多详细信息。

典型用法是 #> nohup /usr/local/bin/myscript.sh &

它将在后台运行脚本,并且不需要您保持登录状态。nohup.out 在运行时将位于当前工作目录中,如果权限不允许,则位于 $HOME/nohup.out 中。然后,您可以检查 nohup.out 的内容以查找需要解决的任何问题并进行相应的处理。

现在,为了解决您的交互性,您可以使用屏幕和 nohup 运行脚本,这样,如果进程挂起等待您的输入,您可以将该进程带回前台。

希望这可以帮助

答案4

如果您想使用屏幕,您可以尝试这样的操作:

ssh user@address screen -d -m <command>

参数-d -m组合使屏幕开始一个新的会话但并不附加到它。

我使用此命令的变体来运行启动时不守护进程的“守护进程”(如 Minecraft),效果很好。我可以screen稍后连接到会话并查看完整输出并像平常一样发出服务器命令。下面是启动脚本变体,它以非 root 用户身份运行屏幕会话(对于 /etc/rc.local):

sudo -u <someuser> -i screen -d -m <command>

相关内容