PHP system() - статус возврата всегда 0

Мне нужно запустить следующие скрипты.

// File: script_a.php
<?php exit(1); ?>

// File: script_b.php
<?php 
     system('PHP скрипт_a.php', $return);
     var_dump($return);
?>

Теперь моя проблема: на моей операционной системе Windows script_b.php отображается int(1), как и ожидалось. На нашем Unix-сервере я всегда получаю int(0), что делает невозможным проверку, если какой-то сбой происходит внутри script_a.php.

Кто-нибудь знает эту проблему и как ее решить?

Ответ 1

Возможно, вы захотите проверить, вызвал ли он правильный исполняемый файл php на машине Unix. Во многих системах UNIX вам нужно будет вызвать исполняемый файл php-cli для php для использования в командной строке. Еще одна вещь, которую нужно проверить, - это разрешения. Может быть, пользователь, выполняющий скрипт_b.php script, не имеет прав на выполнение script_a?

Ответ 2

__halt_compiler() называется где-то, способным проверить, что?

Ответ 3

Попробуйте сделать вызов PHP system с абсолютным путем как для исполняемого файла PHP, так и для имени файла script, например: system('/usr/bin/php /path/to/script_a.php', $return);. Возможно, это проблема. (Вы можете найти абсолютный путь своего исполняемого файла PHP: which php).

Также, как кто-то предложил, попробуйте отладить фактическое возвращаемое значение script_a.php на вашем сервере UNIX, запустив PHP скрипт_a.php; echo $? в командной строке. Это значение echo выводит последнее возвращаемое значение, то есть значение, возвращаемое script_a.php.

В любом случае, я предлагаю сделать include с инструкцией return, как описано в примере № 5 документа include(). Если вы можете адаптировать свои сценарии, как это, это более эффективный способ их передачи.

// File: script_a.php
<?php return 1; ?>

// File: script_b.php
<?php 
     $return = (include 'script_a.php');
     var_dump($return);
?>

Ответ 4

Вы проверили, включен ли safe_mode на сервере unix?

Примечание PHP:

Примечание. Если безопасный режим включен, вы может выполнять только файлы в пределах safe_mode_exec_dir. Для практических причинам, в настоящее время это запрещено иметь компоненты на пути к исполняемый файл.

Или, возможно, системная функция запрещена?

Ответ 5

Я не могу воспроизвести его (PHP 5.3.3, Ubuntu).

Когда я устанавливаю значение exit для чего-то лучшего grep-able, например "666", трассировка возвращаемых сценариев также ожидается:

strace -f php5 script_b.php 2>&1 | grep EXITSTATUS

[pid 18574] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0, NULL) = 18575
waitpid(18574, [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0) = 18574

"-f" to strace позволяет следить за дочерними процессами при использовании системного вызова. "2 > & 1" перенаправляет stderr в stdout, чтобы все grep. Вы также можете подключить его к "| less", но результат длинный и не очень читаемый.

Ответ 6

Я не могу воспроизвести это в своей системе, Ubuntu Hardy. Здесь образец:

/tmp$ mkdir /tmp/sbuzz
/tmp$ cd /tmp/sbuzz
/tmp/sbuzz$ echo '<?php exit(1); ?>' >script_a.php  
/tmp/sbuzz$ cat >script_b.php
<?php 
     system('PHP скрипт_a.php', $return);
     var_dump($return);
?>
/tmp/sbuzz$ PHP скрипт_b.php 
int(1)
/tmp/sbuzz$ echo '<?php exit(2); ?>' >script_a.php  
/tmp/sbuzz$ PHP скрипт_b.php
int(2)
/tmp/sbuzz$ 

Код выхода 0 означает успешное выполнение программы, поэтому похоже, что вы, возможно, используете неправильный скрипт_a.php или, возможно, исполняемый файл "php" не выполняет то, что вы ожидаете? Возможно, у вас есть script, называемый "php", который находится на вашем пути до интерпретатора? Что сообщает "какой php"? В моей системе говорится: "/usr/bin/php".

Если PHP не может найти script, он выйдет с 1, например:

/tmp/sbuzz$ cat script_b.php 
<?php
     system('php doesnt_exist_script_a.php', $return);
     var_dump($return);
?>
/tmp/sbuzz$ PHP скрипт_b.php 
Could not open input file: doesnt_exist_script_a.php
int(1)
/tmp/sbuzz$

В этом случае я изменил script_b.php, чтобы попытаться запустить script, который не существует, и я получаю код выхода 1 (он должен быть 2, если он завершен успешно, потому что я изменил скрипт_a выше), но также показывает ошибку, что он не может запустить программу.

Возможно, вы захотите изменить его, чтобы запустить полный путь к исполняемому файлу PHP:

system('/usr/bin/PHP скрипт_a.php')

а также полный путь к script:

system('/usr/bin/php /tmp/sbuzz/script_a.php')

Вы также можете попробовать выполнить конкретную программу, которая вернет 1, как другую точку данных, например:

system('false')
system('bash -c "exit 69"')

Возможно, вы захотите попробовать код выхода, отличный от 1, что является общим провалом. Вот почему я сделал "выход 69" выше. "false" выйдет с 1.

Также, конечно, попробуйте запустить script_a.php напрямую:

/tmp/sbuzz$ PHP скрипт_a.php 
/tmp/sbuzz$ echo $?
2
/tmp/sbuzz$ 

"$?" это код выхода последней команды запуска в приглашении оболочки.

Ответ 7

Try:

<?php
    die(1);
?>

Если это не удается, проверьте вывод:

strace PHP скрипт_a.php

Ответ 8

Не уверен, связаны ли эти проблемы, но вы можете взглянуть на exec всегда возвращает -1 (или 127), поскольку у меня была аналогичная проблема в прошлом... даже если бы я не решил его на самом деле.

В вашем случае это может быть еще одна проблема, не знаю, как она будет воспроизводиться, но я видел caeses, где возвращаемая строка для неизвестной команды будет возвратной строкой из bash (bash: command not found). На большинстве серверов я ничего не делаю. Вы можете попробовать и проверить настройку оболочки для текущего пользователя (я предполагаю, что это будут www-данные)

Ответ 9

Принимая во внимание ваш комментарий, что ваша проблема возникает в системе UNIX, когда ваш script_b похож на

system ('PHP скрипт_a.php | tee myLogFile', $return);

Вы можете использовать этот синтаксис

system ( "bash -c" PHP скрипт_a.php | tee log.txt; exit\${PIPESTATUS [0]} '", $return);

Сделайте man bash и ищите PIPESTATUS для более подробной информации.

Ответ 10

Я знаю, что это старый поток, но у меня была аналогичная проблема.

Состояние выхода было установлено равным 0, когда я выполнял script в фоновом режиме, что-то вроде

system('PHP скрипт_a.php &', $return);

Не могли бы вы сделать это, а просто обобщить для удобочитаемости?

Ответ 11

вам нужно работать от имени root или использовать sudo для доступа через php.

попробуйте что-то вроде этого: -

system('sudo /usr/bin/php -f script_a.php', $return);

в файле script_b.php

и отредактируйте /etc/sudoers, чтобы добавить следующую строку: -

apache    ALL=(ALL) NOPASSWD: /usr/bin/php -f script_a.php

если php не находится в /usr/bin/php, измените эту ссылку а также упомянуть полный путь к файлу script_a.php somthing как /var/www/html/script _a.php или путь, где он физически находится.

Спасибо.

Ответ 12

Вы можете попробовать передать восьмеричное значение для выхода(). Посмотрите, что будет потом.