đối số giới hạn php execute () thành tập lệnh bash

Dec 02 2020

Thử nghiệm mất bao lâu để chuyển 50000 đối số từ php sang tập lệnh bash, dẫn đến việc tôi không thể chuyển thậm chí 1000 đối số từ php sang tập lệnh bash cùng một lúc, trừ khi tôi có thể?

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

Vì vậy, php của tôi chuyển các đối số cho bash , bash in vào outputFile cùng với bất kỳ lỗi nào. pidfile sẽ giữ pid của quá trình đã được khởi chạy với tệp thực thi này. Lệnh thậm chí không được thực thi vì tôi không thấy quá trình nào được khởi chạy. Có bất kỳ giới hạn nào cho các đối số được truyền trong tệp thực thi không? hoặc từ PHP hoặc trong Linux shell? Tôi đang chạy php 5.4 và Linux Redhat 7 Tôi muốn chạy các quy trình sử dụng song song GNU nhưng vì PHP là đơn luồng (có các thư viện để vượt qua điều này nhưng tôi muốn tránh điều đó). Có lẽ tôi có thể chuyển nó bằng cách nào đó vào một tệp văn bản và thực thi tới một tập lệnh kéo từ tệp văn bản này? Cứu giúp!

** Cập nhật: giới hạn máy của tôi: **
#getconf ARG_MAX
2097152
 
#ulimit -a
kích thước tệp lõi (khối, -c) 0
kích thước seg dữ liệu (kbytes, -d) không giới hạn
ưu tiên lập lịch (-e) 0
kích thước tệp (khối, -f) không giới hạn
tín hiệu đang chờ xử lý (-i) 256634
bộ nhớ bị khóa tối đa (kbyte, -l) 64
kích thước bộ nhớ tối đa (kbyte, -m) không giới hạn
mở tệp (-n) 1024
kích thước ống (512 byte, -p) 8
Hàng đợi tin nhắn POSIX (byte, -q) 819200
ưu tiên thời gian thực (-r) 0
kích thước ngăn xếp (kbytes, -s) 8192
thời gian cpu (giây, -t) không giới hạn
quy trình người dùng tối đa (-u) 4096
bộ nhớ ảo (kbyte, -v) không giới hạn
khóa tệp (-x) không giới hạn

Trả lời

2 ilkkachu Dec 02 2020 at 01:28

Trên hầu hết các hệ thống, hạt nhân giới hạn kích thước của các đối số trong execve()syscall (dòng lệnh args + môi trường vars). Trên Linux, giới hạn liên quan đến kích thước ngăn xếp tối đa, mặc dù thông thường bạn sẽ nhận được tổng ít nhất 2 MB cho giới hạn kích thước ngăn xếp mặc định là 8 MB. Nó cũng giới hạn một đối số duy nhất là 128 kB, hãy xem ví dụ: Có tối đa để mở rộng tên tệp bash không (globbing) và nếu có, nó là gì? và Tăng giới hạn 128KiB cho các biến môi trường trong Linux

Nếu PHP chạy sh -c 'command line'khi bạn gọi exec("command line")thì đối số để -ccó thể vượt quá giới hạn 128 kB đó. Thực tế là dòng lệnh sau đó được chia thành các từ riêng biệt bởi shell sẽ không giúp ích gì.

1 OleTange Dec 02 2020 at 15:41

Khi bạn có nhiều đối số này, bạn muốn chuyển chúng sang GNU Parallel thông qua đầu vào chuẩn (stdin) hoặc qua tệp.

Tôi sẽ làm một cái gì đó như (chưa được kiểm tra):

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

Bằng cách này, bạn có thể tránh được tệp tạm thời.

dwt.bar Dec 02 2020 at 23:48

Vì vậy, với tất cả sự giúp đỡ của bạn, đây là giải pháp của tôi: 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 ) );

TIỀN:

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

Bạn cũng có thể chạy song song với tùy chọn -Dall để có thêm ngữ cảnh những gì đang xảy ra, tôi đã quét gần 40.000 máy chủ trong 7 giờ. Máy chủ web đã thêm tất cả các mục tiêu vào tệp trong vài giây và khi người thực thi của tôi khởi chạy một quy trình nền được sử dụng không phải đợi kết quả (chúng tôi đang xuất nó ra tệp).

Và tập lệnh check.sh cũng đang cập nhật bản ghi cơ sở dữ liệu Mariadb cho một mục tiêu cụ thể khi nó hoạt động.