les arguments limitent php exec () au script bash
Tester combien de temps faudra-t-il pour passer 50000 arguments de php à un script bash, il s'avère que je ne peux même pas passer 1000 arguments de php à un script bash à la fois, à moins que je ne le puisse?
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
Donc mon php passe des arguments au bash , bash imprime au outputFile avec toutes les erreurs. pidfile contiendra le pid du processus qui a été lancé avec cet exécutable. La commande n'est même pas exécutée car je ne vois aucun processus lancé. Y a-t-il une limite pour les arguments passés dans exec? ou de PHP ou dans le shell Linux? J'utilise php 5.4 et Linux Redhat 7 Je veux exécuter des processus en utilisant GNU en parallèle, mais parce que PHP est monothread (il existe des bibliothèques pour transmettre cela mais je préférerais éviter cela). Peut-être que je pourrais le transmettre d'une manière ou d'une autre à un fichier texte et exécuter un script qui extrait de ce fichier texte? Aidez-moi!
** Mise à jour: limites de ma machine: ** #getconf ARG_MAX 2097152 #ulimit -a taille du fichier de base (blocs, -c) 0 taille de segment de données (ko, -d) illimitée priorité de planification (-e) 0 taille de fichier (blocs, -f) illimitée signaux en attente (-i) 256634 mémoire verrouillée max. (Ko, -l) 64 taille maximale de la mémoire (Ko, -m) illimitée fichiers ouverts (-n) 1024 taille du tube (512 octets, -p) 8 Files d'attente de messages POSIX (octets, -q) 819200 priorité en temps réel (-r) 0 taille de la pile (Ko, -s) 8192 temps cpu (secondes, -t) illimité processus utilisateur max (-u) 4096 mémoire virtuelle (Ko, -v) illimitée verrous de fichiers (-x) illimités
Réponses
Sur la plupart des systèmes, le noyau limite la taille des arguments à l' execve()
appel système (ligne de commande args + vars d'environnement). Sous Linux, la limite est liée à la taille maximale de la pile, bien que vous obteniez généralement au moins 2 Mo au total pour la limite de taille de pile par défaut de 8 Mo. Il limite également un seul argument à 128 Ko, voir par exemple Y a-t-il un maximum pour l'expansion des noms de fichiers bash (globbing) et si oui, de quoi s'agit-il? et Augmenter la limite de 128 Ko sur les variables d'environnement sous Linux
Si PHP s'exécute sh -c 'command line'
lorsque vous appelez, exec("command line")
l'argument to -c
pourrait bien dépasser cette limite de 128 Ko. Le fait que la ligne de commande soit ensuite divisée en mots distincts par le shell n'aiderait pas.
Lorsque vous avez autant d'arguments, vous voulez les transmettre à GNU Parallel via une entrée standard (stdin) ou via des fichiers.
Je ferais quelque chose comme (non testé):
$f = popen("parallel","w"); fwrite($f,$commands); close ($f);
De cette façon, vous pourrez peut-être éviter le fichier temporaire.
Donc, avec toute votre aide, voici ma solution: 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 ) );
FRAPPER:
#!/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
Vous pouvez également exécuter votre parallèle avec l'option -Dall pour avoir plus de contexte ce qui se passe, j'ai réussi à scanner près de 40.000 hôtes en 7h. Le serveur Web a ajouté toutes les cibles au fichier en quelques secondes et lorsque mon exécuteur lance un processus d'arrière-plan utilisé n'a pas à attendre le résultat (nous le sortons dans le fichier).
Et le script check.sh met également à jour l'enregistrement de la base de données Mariadb pour une cible particulière au fur et à mesure.