argümanlar php exec () 'i bash betiğiyle sınırlar

Dec 02 2020

50000 argümanı php'den bir bash betiğine geçirmenin ne kadar süreceğini test etmek , yapamadığım sürece php'den bir bash betiğine aynı anda 1000 argüman bile geçiremeyeceğime dönüşüyor ?

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

Benim Yani php için bağımsız değişkenler geçirir bash için, bash baskılar Outputfile hataları ile birlikte. pidfile , bu exec ile başlatılan sürecin pid'ini tutacaktır. Komut çalıştırılmıyor çünkü başlatılan bir işlem görmüyorum. Yürütme sırasında iletilen bağımsız değişkenler için herhangi bir sınır var mı? veya PHP'den veya Linux kabuğundan? Php 5.4 ve Linux Redhat 7 çalıştırıyorum GNU paralel kullanarak süreçleri çalıştırmak istiyorum ama PHP tek iş parçacıklı olduğu için (bunu geçmek için kütüphaneler var ama bundan kaçınmayı tercih ederim). Belki bir şekilde bir metin dosyasına aktarabilir ve bu metin dosyasından alan bir komut dosyasına çalıştırabilirim? Yardım!

** Güncelleme: makine limitlerim: **
#getconf ARG_MAX
2097152
 
#ulimit -a
çekirdek dosya boyutu (bloklar, -c) 0
veri segment boyutu (kbayt, -d) sınırsız
planlama önceliği (-e) 0
dosya boyutu (bloklar, -f) sınırsız
bekleyen sinyaller (-i) 256634
maks kilitli hafıza (kbayt, -l) 64
maksimum bellek boyutu (kbayt, -m) sınırsız
açık dosya (-n) 1024
boru boyutu (512 bayt, -p) 8
POSIX mesaj kuyrukları (bayt, -q) 819200
gerçek zamanlı öncelik (-r) 0
yığın boyutu (kbayt, -s) 8192
cpu süresi (saniye, -t) sınırsız
maksimum kullanıcı işlemleri (-u) 4096
sanal bellek (kbayt, -v) sınırsız
dosya kilitleri (-x) sınırsız

Yanıtlar

2 ilkkachu Dec 02 2020 at 01:28

Çoğu sistemde, çekirdek, değişkenlerin boyutunu execve()sistem çağrısı ile sınırlar (komut satırı bağımsız değişkenleri + ortam değişkenleri). Linux'ta sınır, maksimum yığın boyutuyla ilgilidir, ancak genellikle 8 MB'lık varsayılan yığın boyutu sınırı için en az 2 MB toplam alırsınız. Ayrıca tek bir bağımsız değişkeni 128 kB ile sınırlar, bkz. Örn . Bash dosya adı genişletmesi (globbing) için bir maksimum var mı ve eğer öyleyse, nedir? ve Linux'ta ortam değişkenlerinde 128KiB sınırını yükseltin

PHP sh -c 'command line'çağırdığınızda çalışırsa exec("command line"), argümanı -cbu 128 kB sınırını aşabilir. Komut satırının daha sonra kabuk tarafından farklı kelimelere bölünmesi gerçeği yardımcı olmaz.

1 OleTange Dec 02 2020 at 15:41

Bu kadar çok argümanınız olduğunda, bunları standart girdi (stdin) veya dosyalar yoluyla GNU Paralel'e geçirmek istersiniz.

(Denenmemiş) gibi bir şey yapardım:

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

Bu şekilde geçici dosyadan kaçınabilirsiniz.

dwt.bar Dec 02 2020 at 23:48

İşte tüm yardımınızla burada benim çözümüm: 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 ) );

BASH:

#!/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

Ne olduğunu daha fazla içeriğe sahip olmak için paralelinizi -Dall seçeneğiyle de çalıştırabilirsiniz, 7 saat içinde neredeyse 40.000 ana bilgisayarı taramayı başardım. Web sunucusu tüm hedefleri saniyeler içinde dosyaya ekledi ve benim exec çalıştırdıkça kullanılan bir arka plan işlemi sonucu beklemek zorunda değiliz (dosyayı dosyaya gönderiyoruz).

Ayrıca check.sh betiği, belirli bir hedef için Mariadb veritabanı kaydını da güncelliyor.