Usypianie interpretera PHP wywołanego z linii poleceń

Problem dotyczy uruchamiania interpretatora php z linii poleceń. W najprostszym przypadku:

php &

zwraca:

[1]+ Stopped php

Oczekiwałbym, że zadanie tak jak zazwyczaj przy korzystaniu z & będzie wykonywało się w tle. Wywołanie bg nie pomaga (proces dalej jest uśpiony). Wywołanie fg powoduje, że proces wykonuje się dalej poprawnie (przy okazji blokując terminal). W przypadku skryptów napisanych w bash lub zwykłych programów nie ma takich problemów. Domyślam się, że problem może być z konfiguracją PHP, ale nie mam zupełnie pomysłu co z tym zrobić?

Interpretator terminala się zawiesza, bo nie jest procesem pierwszorzędnym tego terminala. Pewnie działa w trybie interaktywnym. Gdybyś podał mu plik do wykonania, to by się nie zawiesił.

Co chcesz osiągnąć?

Chcę uruchomić skrypt PHP w tle. Zwykle w linuksie robi się to dodając & na końcu zadania. Zwykle, na innych maszynach uruchamianie skryptów PHP w tle nie powoduje problemów. Tutaj jest inaczej.

W przykładzie podanym wyżej nie podałem pliku, aby pokazać, że cała sprawa jest niezależna od zawartości skryptu. Poniższe przykłady zachowują się tak samo (czyli próba uruchomienia skryptu PHP w tle kończy się jego zatrzymaniem, zanim cokolwiek zdąży zrobić. W przypadku gdy uruchamiam zadanie bez & wszystko wykonuje się normalnie i do końca):

php plik.php &

./plik2.php &

(plik2.php zaczyna się od adresu intepretatora:

#!/usr/bin/php

). Z tym trybem interaktywnym może być coś na rzeczy, ale całość jest nie czuła na zastosowanie przełącznika -a.

A w cronie nie można?

Tylko z tym “&” uważaj żebyś nie zrobił forkbomby;-)

Jeśli chcesz odpalić php w trybie interaktywnym musisz:

sudo apt-get install php5-cli

[*:278j8p19]php w trybie interaktywnym odpalasz przez

php5 -a

Teraz wracając do Twojego problemu…

php

…działa - tzn odpala php w tle. Jeśli chcesz ubić to

killall -9 php

Jeśli chcesz odpalić skrypcik w tle to dajesz

php test.php out.txt

Bez out.txt skrypt nie wykona się. Nie pytaj dlaczego - szczegółów nie znam ale tak jest (przynajmniej w przypadku kiedy coś ma wyświetlic na konsoli (echo itp.). Przykładowy kod powinien wyglądać nastepująco (test.php):

?php


// Show all information, defaults to INFO_ALL

phpinfo();


// Show just the module information.

// phpinfo(8) yields identical results.

phpinfo(INFO_MODULES);


?

:idea: Sprawdzone na Xubuntu 12.04 (32bit). Powinno działać na każdym *buntu/debianie.

No własnie kolego nie działa. Jak twierdzisz, że trzeba przekierować plik, to dorzucę jeszcze parę przykładów, które nie działają:

php test.php > plik.log &

./test.php > plik.log &

php test.php &> plik.log &

./test.php &> plik.log &

tzn skrypt się zatrzymuje

[1]+ Stopped php

W ten sposób uruchamiałem zadania na kilku maszynach z różnym systemem operacyjnym i chodziły bez problemu. Akurat nie na tym:

cat /proc/version

Linux version 2.6.32-220.4.1.el6.x86_64 (mockbuild@sl6.fnal.gov) (gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC) ) #1 SMP Mon Jan 23 17:20:44 CST 2012

[a@main 3]$ php -v

PHP 5.3.3 (cli) (built: Feb 2 2012 17:19:29)

Copyright (c) 1997-2010 The PHP Group

Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

Dzięki za uwagę, ale w cronie nie można, o nadmiar forków też się nie martw, no ale dzięki. – Dodane 04.05.2012 (Pt) 14:04 – Znalazłem jakieś rozwiązanie. Z tego co rozumiem problem wynika z włączenia w trakcie instalacji “GNU Readline”. Zasadniczo domyślne paczki dostępne przez yum lub apt-get są dostępne z tą opcją od jakieś niedawnej wersji PHP (nie sprawdzałem dokładnie której, ale późniejszej niż 5.1.6). Rozwiązania są dwa. Albo pobrać źródła PHP i samemu je skompilować wyłączając odpowiednie opcje, albo skrypty wywoływać w sposób poniższy:

php skrypt.php < /dev/null &

Pozdrawiam