Как я могу написать «shutdown -r 1» и вернуть статус выхода?

Я пишу программу, которая в какой-то момент вызовет сценарий оболочки. Мне нужен этот сценарий оболочки (bash или, при необходимости, будет работать PHP 4+), который будет вызываться программой и возвращать статус выхода, который я могу передать до того, как истечет 1 минута и система перезагрузится.

Вот идея того, что я имею в виду, лучше всего, как я могу описать:

  • Программа вызывает сценарий «перезагрузки»
  • Сценарий перезагрузки запускает «shutdown -r 1», а затем завершает работу со статусом 0.
  • Программное эхо выходит из состояния выхода
  • Сервер перезагружается

Я могу заставить работать все, кроме статуса выхода - независимо от того, что я пытаюсь сделать, программа никогда не выходит из своего цикла, ожидая статуса выхода, поэтому она никогда ничего не возвращает, но перезагрузка все равно происходит. Эта программа запускает другие сценарии, которые возвращают статусы выхода, поэтому мне нужен и этот, чтобы поддерживать функциональность и все такое...

Любая помощь приветствуется!

EDIT. Программа, вызывающая сценарий перезагрузки, представляет собой сценарий PHP, работающий в цикле. Когда происходят определенные события, программа запускает определенные сценарии и выводит статус выхода. Все они работают, но это никогда не возвращает статус выхода.

Скрипты вызываются с помощью system($cmd), где $cmd — это './scriptname.sh'


person Mistiry    schedule 25.10.2011    source источник
comment
Вы уверены, что проблема в вызываемом скрипте?   -  person marinara    schedule 25.10.2011
comment
Ну, насколько я могу судить, во всяком случае. У меня нет проблем с другими скриптами, которые вызывает программа, она нормально захватывает и отображает статусы выхода. Только этот скрипт не работает :(   -  person Mistiry    schedule 25.10.2011
comment
попробуйте включить отладку оболочки в любом месте, где у вас есть сценарий оболочки? set -vx ? Затем вы можете увидеть, что выполняет завершение, а что выполняется, но не завершает. Удачи.   -  person shellter    schedule 25.10.2011


Ответы (3)


Предполагая, что вы открываете процесс с помощью proc_open, вызов proc_get_status должен вернуть массив, содержащий код выхода.

person Jeff Day    schedule 25.10.2011
comment
Я отредактировал вопрос, чтобы дополнительно объяснить, как работает программа и вызываются сценарии. Спасибо за ваш вклад! Я изучаю proc_open как возможную альтернативу, но это означает массу дополнительной работы по кодированию :( - person Mistiry; 25.10.2011
comment
Вы передаете необязательный второй параметр в system(), чтобы получить статус возврата? - person Jeff Day; 26.10.2011

Вы можете создать сценарий bash, который запускает процесс завершения работы:

#!/bin/bash
shutdown -r 1 &
exit 0

Это возвращает управление родительской оболочке, которая получает «0» в качестве кода выхода.

person imm    schedule 25.10.2011
comment
Вот как я это пробовал, и он не возвращал статус выхода ... также пробовал подобное в PHP, но безрезультатно. :( - person Mistiry; 25.10.2011

К сожалению, вы не можете полагаться на PHP-функции system() и exec() для получения правильного возвращаемого значения, но с небольшим обходным решением в BASH< /strong> можно действительно эффективно разобрать код выхода:

function runthis($command) {
  $output = array();
  $retcode = -1;
  $command .= " &2>1; echo $?";

  exec($command, $output, $retcode);
  $retcode = intval(array_pop($output));

  return $retcode;
}

if (runthis("shutdown -r 1") !== 0) echo "Command failed!\n";

Позвольте мне сломать, что делает код:

  • $command .= " &2>1; echo $?"; — разверните команду, чтобы мы передавали stderr в stdout, затем запускаем echo $?
  • echo $? — это специальный параметр bash, который расширяется до кода выхода последней выполненной команды.
  • exec($command, $output, $retcode); - выполнить команду. (Здесь $retcode является просто заполнителем, так как возвращенные данные не заслуживают доверия. Мы перезапишем их позже.) Вывод команды будет записан в $output в виде массива. Каждый элемент будет представлять отдельную строку.
  • $retcode = intval(array_pop($output)); - разобрать последнюю строку как целое число. (поскольку последней командой будет echo $?, это всегда будет фактический код выхода.

И это все, что вам нужно! Хотя это действительно грубый код, который подвержен ошибкам при неправильном использовании, он идеально подходит для выполнения более простых задач и всегда дает правильный код выхода.

Для более профессионального (и программного) подхода вам нужно изучить PHP-функции pnctl, posix, stream, а также Linux. обработка трубы.

person Gergely Lukacsy    schedule 07.01.2016