2011-12-05 44 views
8

Đối với một trang web, tôi cần để có thể bắt đầu và dừng quá trình daemon. Những gì tôi hiện đang làm làKhởi động một daemon từ PHP

exec("sudo /etc/init.d/daemonToStart start"); 

Quá trình daemon được bắt đầu, nhưng Apache/PHP bị treo. Làm một ps aux tiết lộ rằng sudo chính nó đã thay đổi thành một quá trình zombie, có hiệu quả giết chết tất cả tiến bộ hơn nữa. Đây có phải là hành vi bình thường khi cố gắng để bắt đầu một daeomon từ PHP?

Và có, Apache có quyền thực hiện lệnh /etc/init.d/daemonToStart. Tôi thay đổi tập tin/etc/sudoers để cho phép nó làm như vậy. Không, tôi đã không cho phép Apache có thể thực hiện bất kỳ loại lệnh nào, chỉ một số ít để cho phép trang web hoạt động.

Dù sao, quay trở lại câu hỏi của tôi, có cách nào để cho phép PHP khởi động các trình tiện ích theo cách mà không có quá trình tạo zombie nào không? Tôi hỏi điều này bởi vì khi tôi làm ngược lại, dừng một daemon đã bắt đầu, hoạt động tốt.

+0

Nên không có được một 'lập luận start'? – ZeissS

+0

Đúng, tôi quên thêm câu hỏi đó vào câu hỏi. Trong mã của tôi, tôi có nó. Nhưng, tôi sẽ chỉnh sửa câu hỏi để hoàn thành. – ThaMe90

Trả lời

10

Thử thêm > /dev/null 2>&1 & vào lệnh.

Vì vậy, đây:

exec("sudo /etc/init.d/daemonToStart > /dev/null 2>&1 &"); 

Chỉ trong trường hợp bạn muốn biết những gì nó làm/tại sao:

  • > /dev/null - chuyển hướng STDOUT đến/dev/null (Blackhole nó, hay nói cách khác)
  • 2>&1 - chuyển hướng STDERR sang STDOUT (cũng làm lỗ đen nó)
  • & tách quy trình và chạy ở chế độ nền
+0

Cảm ơn, điều đó đã xảy ra! – ThaMe90

+0

Cảm ơn bạn đã giải thích thêm, nhưng vì đầu ra được bôi đen, nên bất kỳ mã nào đã được thực thi sau khi daemon đã bắt đầu, sẽ được truyền đi. Tôi phải kiểm tra xem quá trình đã bắt đầu chưa, nhưng mã đó không bao giờ bị bắn ... – ThaMe90

+1

Khi bạn bắt đầu một quá trình bằng cách sử dụng phương pháp này, nó sẽ xuất ra PID của quá trình đã được tạo. Bạn có thể thực hiện điều này, và sau đó (ví dụ) thực thi 'ps | grep $ pidOfProcessYouJustStarted' để đảm bảo nó đang chạy. – DaveRandom

0

Tôi chưa bao giờ thử bắt đầu một daemon từ PHP, nhưng tôi đã thử chạy các lệnh shell khác, với nhiều rắc rối. Dưới đây là một vài điều tôi đã thử, trong quá khứ:

  • Theo câu trả lời của DaveRandom, hãy thêm /dev/null 2>&1 & vào cuối lệnh của bạn. Điều này sẽ chuyển hướng lỗi đến đầu ra tiêu chuẩn. Sau đó bạn có thể sử dụng đầu ra này để gỡ lỗi.
  • Đảm bảo PATH của người dùng máy chủ web của bạn chứa tất cả các tệp nhị phân được tham chiếu bên trong tập lệnh daemon của bạn. Bạn có thể làm điều này bằng cách gọi số exec('echo $PATH; whoami;). Điều này sẽ cho bạn biết người dùng PHP đang chạy dưới, và biến PATH hiện tại của nó.
2

Tôi đã gặp vấn đề tương tự.

Tôi đồng ý với DaveRandom, bạn phải chặn mọi đầu ra (stdout và stderr). Nhưng không cần phải khởi chạy trong quá trình khác với kết thúc '&': hàm exec() không thể kiểm tra mã trả về nữa và trả về ok ngay cả khi có lỗi ...

Và tôi thích lưu trữ đầu ra trong một tệp tạm thời, thay vì 'blackhole'it. giải pháp làm việc:

$temp = tempnam(sys_get_temp_dir(), 'php'); 
exec('sudo /etc/init.d/daemonToStart >'.$temp.' 2>&1'); 

Chỉ cần đọc nội dung tập tin sau và xóa tập tin tạm thời:

$output = explode("\n", file_get_contents($temp)); 
@unlink($temp); 
Các vấn đề liên quan