Argumente beschränken php exec () auf Bash-Skript
Wenn Sie testen, wie lange es dauern wird, bis 50000 Argumente von PHP an ein Bash-Skript übergeben werden, kann ich nicht einmal 1000 Argumente von PHP gleichzeitig an ein Bash-Skript übergeben, es sei denn, ich kann?
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
Mein PHP übergibt also Argumente an die Bash , Bash druckt zusammen mit etwaigen Fehlern an die Ausgabedatei . pidfile enthält pid des Prozesses, der mit dieser Ausführung gestartet wurde. Der Befehl wird nicht einmal ausgeführt, da kein Prozess gestartet wird. Gibt es eine Grenze für übergebene Argumente in exec? oder von PHP oder in Linux Shell? Ich verwende PHP 5.4 und Linux Redhat 7. Ich möchte Prozesse mit GNU parallel ausführen, aber da PHP Single-Threaded ist (es gibt Bibliotheken, die dies übergeben, aber ich würde es vorziehen, dies zu vermeiden). Vielleicht könnte ich es irgendwie an eine Textdatei übergeben und an ein Skript ausführen, das aus dieser Textdatei abgerufen wird? Hilfe!
** Update: meine Maschinenlimits: ** #getconf ARG_MAX 2097152 #ulimit -a Kerndateigröße (Blöcke, -c) 0 Datenseg-Größe (KB, -d) unbegrenzt Planungspriorität (-e) 0 Dateigröße (Blöcke, -f) unbegrenzt anstehende Signale (-i) 256634 Maximal gesperrter Speicher (KB, -l) 64 Maximale Speichergröße (KB, -m) unbegrenzt Dateien öffnen (-n) 1024 Rohrgröße (512 Bytes, -p) 8 POSIX-Nachrichtenwarteschlangen (Bytes, -q) 819200 Echtzeitpriorität (-r) 0 Stapelgröße (kbytes, -s) 8192 CPU-Zeit (Sekunden, -t) unbegrenzt max Benutzerprozesse (-u) 4096 virtueller Speicher (kbytes, -v) unbegrenzt Dateisperren (-x) unbegrenzt
Antworten
Auf den meisten Systemen beschränkt der Kernel die Größe der Argumente auf den execve()
Systemaufruf (Befehlszeilenargumente + Umgebungsvariablen). Unter Linux bezieht sich das Limit auf die maximale Stapelgröße, obwohl Sie normalerweise mindestens 2 MB für das Standardlimit für die Stapelgröße von 8 MB erhalten. Es beschränkt auch ein einzelnes Argument auf 128 kB, siehe z. B. Gibt es ein Maximum für die Erweiterung des Dateinamens (Globbing) und wenn ja, was ist das? und Erhöhen Sie das 128-KB-Limit für Umgebungsvariablen unter Linux
Wenn PHP sh -c 'command line'
beim Aufruf ausgeführt exec("command line")
wird, kann das Argument to -c
diese Grenze von 128 kB durchaus überschreiten. Die Tatsache, dass die Befehlszeile anschließend von der Shell in verschiedene Wörter aufgeteilt wird, würde nicht helfen.
Wenn Sie so viele Argumente haben, möchten Sie diese über die Standardeingabe (stdin) oder über Dateien an GNU Parallel übergeben.
Ich würde so etwas wie (ungetestet) machen:
$f = popen("parallel","w"); fwrite($f,$commands); close ($f);
Auf diese Weise können Sie möglicherweise die temporäre Datei vermeiden.
Mit all Ihrer Hilfe ist hier meine Lösung: 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
Sie können Ihre Option auch parallel mit -Dall ausführen, um mehr Kontext zu erhalten. Ich habe es geschafft, in 7 Stunden fast 40.000 Hosts zu scannen. Der Webserver fügte der Datei innerhalb von Sekunden alle Ziele hinzu, und wenn mein Exec einen verwendeten Hintergrundprozess startet, muss er nicht auf das Ergebnis warten (wir geben es in die Datei aus).
Das Skript check.sh aktualisiert außerdem den Mariadb-Datenbankdatensatz für ein bestimmtes Ziel.