argumen membatasi php exec () ke skrip bash

Dec 02 2020

Menguji berapa lama waktu yang dibutuhkan untuk meneruskan 50000 argumen dari php ke skrip bash, ternyata saya tidak dapat meneruskan bahkan 1000 argumen dari skrip php ke bash sekaligus, kecuali saya bisa?

PHP:
    
$array = fetch_results_from_working_pool_temp_table (); $outputfile = "/var/www/html/outputFile";
$pidfile = "/var/www/html/pidFile"; $id = "";
$array_check=array(); foreach ( $array as $row => $column ) {
    $id .= $column ['id'];
        $id .= " "; } $cmd = "sudo /bin/bash /var/www/html/statistics/pass_all.sh {$id}"; exec( sprintf ( "%s >> %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile ) ); bash: #!/bin/bash for ip in "$@"
do 
    echo "${ip}" 
done

Jadi php saya memberikan argumen ke bash , bash mencetak ke outputFile bersama dengan kesalahan apa pun. pidfile akan menampung pid dari proses yang diluncurkan dengan exec ini. Perintah tersebut bahkan tidak dijalankan karena saya tidak melihat proses yang diluncurkan. Apakah ada batasan untuk argumen yang diteruskan di exec? atau dari PHP atau di shell Linux? Saya menjalankan php 5.4 dan Linux Redhat 7 Saya ingin menjalankan proses menggunakan GNU paralel tetapi karena PHP adalah single-threaded (ada pustaka untuk meneruskan ini tetapi saya lebih suka menghindari itu). Mungkin saya bisa meneruskannya ke file teks dan mengeksekusinya ke skrip yang menarik dari file teks ini? Tolong!

** Pembaruan: batas mesin saya: **
#getconf ARG_MAX
2097152
 
#ulimit -a
ukuran file inti (blok, -c) 0
ukuran seg data (kbytes, -d) tidak terbatas
penjadwalan prioritas (-e) 0
ukuran file (blok, -f) tidak terbatas
sinyal tertunda (-i) 256634
memori terkunci maks (kbytes, -l) 64
ukuran memori maks (kbytes, -m) tidak terbatas
buka file (-n) 1024
ukuran pipa (512 byte, -p) 8
Antrian pesan POSIX (byte, -q) 819200
prioritas waktu-nyata (-r) 0
ukuran tumpukan (kbytes, -s) 8192
waktu cpu (detik, -t) tidak terbatas
proses pengguna maks (-u) 4096
memori virtual (kbytes, -v) tidak terbatas
kunci file (-x) tidak terbatas

Jawaban

2 ilkkachu Dec 02 2020 at 01:28

Pada kebanyakan sistem, kernel membatasi ukuran argumen ke execve()syscall (baris perintah args + environment vars). Di Linux, batas tersebut terkait dengan ukuran tumpukan maksimum, meskipun biasanya Anda akan mendapatkan setidaknya total 2 MB untuk batas ukuran tumpukan default 8 MB. Ini juga membatasi satu argumen hingga 128 kB, lihat misalnya Apakah ada batas maksimum untuk perluasan nama file (globbing) dan jika ya, apa itu? dan Naikkan batas 128KiB pada variabel lingkungan di Linux

Jika PHP berjalan sh -c 'command line'saat Anda memanggil exec("command line")maka argumen untuk -cbisa melebihi batas 128 kB. Fakta bahwa baris perintah kemudian dibagi menjadi kata-kata yang berbeda oleh shell tidak akan membantu.

1 OleTange Dec 02 2020 at 15:41

Jika Anda memiliki banyak argumen, Anda ingin meneruskannya ke GNU Parallel melalui input standar (stdin) atau melalui file.

Saya akan melakukan sesuatu seperti (belum teruji):

$f = popen("parallel","w"); fwrite($f,$commands); close ($f);

Dengan cara ini Anda mungkin dapat menghindari file sementara.

dwt.bar Dec 02 2020 at 23:48

Jadi dengan semua bantuan Anda, inilah solusi saya: PHP:

function scan_targets() {

$targetsFile= "[absolute path to the file]/targets"; $array_with_targets = fetch_from_db (); //function that gets me all the targets
$outputfile = "[absolute path to the file]/outputFile"; //output from parallel script $pidfile = "[absolute path to the file]/pidFile"; //PID of the process
$target = ""; foreach ( $array_with_targets as $row => $column ) {
    $id .= $column ['id'];
        $id .= " "; } file_put_contents($targetsFile, $ip) ; $cmd = "/bin/bash [absolute path to the file]/pass_targets.sh";
exec( sprintf ( "%s >> %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile ) );

PESTA:

#!/bin/bash

#appending arguments to the command
targets_array=()
IFS=" "
while read -r field || [ -n "$field" ]; do targets_array+=("$field")
done <[absolute path to the file]/targets
    
parallel bash [absolute path to the file]/check.sh ::: $targets_array

Anda juga dapat menjalankan paralel dengan opsi -Dall untuk mengetahui lebih banyak konteks tentang apa yang terjadi, saya berhasil memindai hampir 40.000 host dalam 7 jam. Server web menambahkan semua target ke file dalam hitungan detik dan saat exec saya meluncurkan proses latar belakang yang digunakan tidak harus menunggu hasilnya (kami mengeluarkannya ke file).

Dan skrip check.sh juga memperbarui rekaman basis data Mariadb untuk target tertentu saat berjalan.