argümanlar php exec () 'i bash betiğiyle sınırlar
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
Ç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.
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.
İş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.