У меня есть несколько автономных скриптов, которые запускают команды на удаленных машинах через ssh. Эти сценарии полагаются на получение stdout, stderr и код возврата каждой запущенной команды. Я хочу иметь возможность отслеживать ход выполнения сценариев на каждой целевой машине, чтобы я мог видеть, не зависло ли что-то, и, возможно, вмешаться, если это необходимо.
Моя первоначальная идея заключалась в том, чтобы скрипты запускали команды в сеансе экрана, чтобы человек, наблюдающий за человеком, мог просто подключиться к сеансу с помощью screen -x
. Однако сделать это из сценария было сложно, поскольку экран - интерактивная программа. Я могу отправить команду сеансу экрана с помощью screen -S session -X stuff "command^M"
, но тогда я не получаю требуемые выходные данные и код возврата.
Вторая идея заключалась в том, чтобы поставить script /path/to/log
в ~/.bash_profile
и записать весь сеанс в файл. Тогда контролирующий может просто отслеживать файл журнала. Однако это не обеспечивает той интерактивности, которую я искал.
Есть идеи, как решить эту проблему?
Много человеческого общения .. Я бы посоветовал:
В этом сценарии человека предупреждают только тогда, когда что-то идет не так. У них есть возможность просмотреть сообщение журнала через веб-интерфейс, подтвердить их, чтобы другие люди в команде знали, что с ними работают, и решить, когда предпринять действия, в зависимости от характера проблемы.
Я использую php в качестве сценария оболочки для управления моим сервером 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;
}
}
Вы должны посмотреть на Fabric. Он делает именно то, что вы описываете, что ищете. Вам нужно будет написать сценарий в стиле Python. Вы сможете запускать свои скрипты. Возможно, вам будет более эффективным выполнить команду из Fabric. Вы поймете, что я имею в виду; запустите учебник. http://docs.fabfile.org/0.9.2/
Я хотел бы предложить использовать «nohup» - это выведет стандартный вывод в nohup.out. Вы можете запустить скрипт с помощью nohup и безопасно выйти из системы, и он продолжит работу. Посетите man nohup для получения более подробной информации.
Типичное использование: #> nohup /usr/local/bin/myscript.sh &
Он запустит скрипт в bg и не потребует, чтобы вы оставались в системе. Nohup.out будет находиться в текущем рабочем каталоге при запуске или $ HOME / nohup.out, если perms не позволяют этого. Затем вы можете проверить содержимое nohup.out на наличие проблем, которые вам нужно решить, и решить их соответствующим образом.
Теперь, чтобы решить вашу интерактивность, вы можете запустить скрипт, используя screen и nohup, таким образом, вы можете вернуть процесс на передний план, если он завис в ожидании вашего ввода.
Надеюсь это поможет
Если вы хотите использовать экран, вы можете попробовать что-то вроде этого:
ssh user@address screen -d -m <command>
В -d -m
комбинация аргументов заставляет screen начать новую сессию, но не присоединяется к ней.
Я использую вариант этой команды для запуска «демонов», которые не демонизируются (например, Minecraft) при запуске, и это прекрасно работает. Я могу подключиться к screen
позже, просмотрите полный вывод и выполните команды сервера, как обычно. Ниже представлен вариант сценария запуска, который запускает сеанс экрана от имени пользователя, отличного от пользователя root (для /etc/rc.local):
sudo -u <someuser> -i screen -d -m <command>