Saya punya skrip PHP yang perlu menjalankan skrip shell tetapi tidak peduli sama sekali tentang hasilnya. Script shell membuat beberapa panggilan SOAP dan lambat untuk diselesaikan, jadi saya tidak ingin memperlambat permintaan PHP sementara menunggu balasan. Faktanya, permintaan PHP harus bisa keluar tanpa menghentikan proses shell.
Saya telah melihat ke berbagai exec()
, shell_exec()
, pcntl_fork()
, dll fungsi, namun tidak satupun dari mereka tampaknya menawarkan apa yang saya inginkan. (Atau, jika mereka melakukannya, tidak jelas bagiku caranya.) Ada saran?
php
asynchronous
shell
AdamTheHutt
sumber
sumber
nice
danionice
mencegah skrip shell membanjiri sistem Anda (mis./usr/bin/ionice -c3 /usr/bin/nice -n19
)Jawaban:
Jika "tidak peduli dengan output", bisakah eksekutif skrip dipanggil dengan
&
latar belakang proses?EDIT - memasukkan apa yang dikomentari @ AdamTheHut ke pos ini, Anda dapat menambahkan ini ke panggilan ke
exec
:Itu akan mengarahkan ulang
stdio
(pertama>
) danstderr
(2>
) ke/dev/null
dan berjalan di latar belakang.Ada cara lain untuk melakukan hal yang sama, tetapi ini adalah yang paling sederhana untuk dibaca.
Alternatif untuk pengalihan ganda di atas:
sumber
&> /dev/null &
, xdebug tidak akan menghasilkan log jika Anda menggunakan ini. Periksa stackoverflow.com/questions/4883171/…/dev/null
adalah praktik yang lebih baik, karena menulis ke FD yang ditutup menyebabkan kesalahan, sedangkan upaya membaca atau menulis/dev/null
hanya diam-diam tidak melakukan apa-apa.Saya menggunakan di untuk ini, karena benar-benar mulai proses yang independen.
sumber
www-data
) tidak memiliki izin untuk menggunakanat
dan Anda tidak dapat mengonfigurasinya, Anda dapat mencoba menggunakan<?php exec('sudo sh -c "echo \"command\" | at now" ');
Jikacommand
berisi kutipan, lihat escapeshellarg untuk menghemat sakit kepala Andaecho "sudo command" | at now
dan berkomentarwww-data
di/etc/at.deny
Untuk semua pengguna Windows: Saya menemukan cara yang baik untuk menjalankan skrip PHP asinkron (sebenarnya berfungsi dengan hampir semua).
Ini didasarkan pada perintah popen () dan pclose (). Dan berfungsi dengan baik pada Windows dan Unix.
Kode asli dari: http://php.net/manual/en/function.exec.php#86329
sumber
myscript.js
tetapi sebaliknya, Anda akan menulisnode myscript.js
. Yaitu: node adalah executable, myscript.js adalah script yang harus dieksekusi. Ada perbedaan besar antara executable dan skrip.php artisan
cukup beri komentar di sini sehingga tidak perlu melacak mengapa itu tidak akan bekerja dengan perintahDi linux Anda dapat melakukan hal berikut:
Ini akan mengeksekusi perintah pada prompt perintah dan kemudian hanya mengembalikan PID, yang Anda dapat memeriksa> 0 untuk memastikan itu berfungsi.
Pertanyaan ini serupa: Apakah PHP memiliki threading?
sumber
action=generate var1_id=23 var2_id=35 gen_id=535
segmen). Juga, karena OP bertanya tentang menjalankan skrip shell, Anda tidak memerlukan bagian khusus PHP. Kode terakhirnya adalah:$cmd = 'nohup nice -n 10 /path/to/script.sh > /path/to/log/file.log & printf "%u" $!';
nice
tetapi jugaionice
.&
menjalankan kode sebelumnya di latar belakang, kemudianprintf
digunakan untuk output terformat dari$!
variabel yang berisi PIDphp-execute-a-background-process memiliki beberapa saran bagus. Saya pikir saya cukup bagus, tapi saya bias :)
sumber
Di Linux, Anda dapat memulai proses di utas independen baru dengan menambahkan tanda dan di akhir perintah
Di Windows, Anda dapat menggunakan perintah DOS "mulai"
sumber
start
perintah di windows, itu tidak berjalan secara tidak sinkron ... Bisakah Anda memasukkan sumber dari mana Anda mendapatkan informasi itu?/B
parameternya. Saya sudah menjelaskannya di sini: stackoverflow.com/a/34612967/1709903cara yang tepat (!) untuk melakukannya adalah dengan
fork fork, setsid memberi tahu proses saat ini untuk menjadi master satu (tidak ada orangtua), mengeksekusi memberitahu proses panggilan untuk digantikan oleh yang dipanggil. sehingga orang tua dapat berhenti tanpa mempengaruhi anak.
sumber
Saya menggunakan ini ...
(Dimana
PHP_PATH
const didefinisikan sukadefine('PHP_PATH', '/opt/bin/php5')
atau serupa)Itu lewat dalam argumen melalui baris perintah. Untuk membacanya dalam PHP, lihat argv .
sumber
Satu-satunya cara saya menemukan yang benar-benar bekerja untuk saya adalah:
sumber
shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown")
dan yang saya dapatkan adalah:sh: 1: disown: not found
Saya juga menemukan Komponen Proses Symfony berguna untuk ini.
Lihat cara kerjanya di repo GitHub -nya .
sumber
proc_*
fungsi internal.Anda juga dapat menjalankan skrip PHP sebagai daemon atau cronjob :
#!/usr/bin/php -q
sumber
Gunakan fifo bernama.
Kemudian, kapan pun Anda ingin memulai tugas yang sudah berjalan lama, cukup tulis baris baru (bukan blokir ke file pemicu.
Selama input Anda lebih kecil dari
PIPE_BUF
dan ini adalahwrite()
operasi tunggal , Anda dapat menulis argumen ke fifo dan membuatnya muncul seperti$REPLY
dalam skrip.sumber
tanpa menggunakan antrian, Anda dapat menggunakan yang
proc_open()
seperti ini:sumber