パラメータはphp exec()をbashスクリプトに制限します。

パラメータはphp exec()をbashスクリプトに制限します。

50000個のパラメータをPHPからbashスクリプトに渡すのにかかる時間をテストしてください。結果は次のとおりです。できない場合は、PHPからbashスクリプトに一度に1000個のパラメータを渡すことはできませんか?

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

だから私のPHPパラメータ渡し強く打つ、bashは次に印刷します。結果ファイルそして任意のエラー。pidファイルこのexecで始まったプロセスのpidが保存されます。 プロセスが開始されないため、コマンドは実行されません。execに渡されるパラメータに制限はありますか?それともPHPやLinuxシェルで? 私はPHP 5.4とLinux Redhat 7を実行しています。 私はGNUを使ってプロセスを並列に実行したいのですが、PHPはシングルスレッドなので(これを提供するライブラリがありますが、私はそれを避けたい)。たぶんそれをテキストファイルに渡し、そのテキストファイルから抽出されたスクリプトを実行できますか?助ける!

**更新:マイコンピュータの制限:**
#getconf ARG_MAX
2097152
 
#ulimit -a
コアファイルサイズ(ブロック、-c)0
無制限のデータセグメントサイズ(KB、-d)
スケジューリング優先順位(-e)0
無制限のファイルサイズ(ブロック、-f)
保留中の信号(-i)256634
最大ロックされたメモリ(KB、-l)64
最大メモリサイズ(KB、-m)無制限
ファイルを開く(-n)1024
パイプサイズ(512バイト、-p)8
POSIXメッセージキュー(バイト、-q)819200
リアルタイム優先順位(-r)0
スタックサイズ(キロバイト、-s)8192
CPU時間(秒、-t)無制限
最大ユーザープロセス数(-u)4096
仮想メモリ(キロバイト、-v)無制限
ファイルロック(-x)無制限

答え1

ほとんどのシステムでは、カーネルはexecve()システムコール引数(コマンドライン引数+環境変数)のサイズを制限します。 Linuxでは、制限は最大スタックサイズに関連していますが、通常、デフォルトのスタックサイズ制限が8MBの場合、合計サイズは少なくとも2MBになります。また一つパラメータは128kBです。Bashファイル名拡張子(ワイルドカード)に最大制限はありますか?それでは何ですか?そしてLinuxの環境変数の制限が128KiB増加しました。

sh -c 'command line'PHPを呼び出すときにPHPが実行されている場合、exec("command line")パラメータが-c128kB制限を超える可能性があります。コマンドラインがシェルによって別の単語に分割されるという事実は役に立ちません。

答え2

引数が多すぎる場合は、標準入力(stdin)またはファイルを介して引数をGNU Parallelに渡そうとします。

私は(テストされていない)次のようなことをします。

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

これにより、一時ファイルを回避できます。

答え3

だからあなたの助けを借りて、私の解決策は次のとおりです。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 ) );

大きな打撃:

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

-Dallオプションを使用して並列に実行して、何が起こっているのかを確認することもできます。私は7時間でほぼ40,000のホストをスキャンしました。 Webサーバーは、数秒以内にすべてのターゲットをファイルに追加し、私のexecが使用されたバックグラウンドプロセスを開始するときに結果を待つ必要はありません(ファイルとして出力します)。

check.sh スクリプトは、特定の宛先の Mariadb データベースレコードも更新します。

関連情報