อาร์กิวเมนต์ จำกัด php exec () ไว้ที่ bash script
การทดสอบว่าจะใช้เวลานานแค่ไหนในการส่งอาร์กิวเมนต์ 50000 จาก php ไปยัง bash script ปรากฎว่าฉันไม่สามารถส่งอาร์กิวเมนต์จาก php ไปยัง bash script ได้ในคราวเดียวเว้นแต่จะทำได้
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 , bash จะพิมพ์ไปยังoutputFileพร้อมกับข้อผิดพลาดใด ๆ pidfileจะเก็บ pid ของกระบวนการที่เปิดตัวด้วย exec นี้ คำสั่งไม่ได้ถูกเรียกใช้งานด้วยซ้ำเพราะฉันไม่เห็นกระบวนการเปิดใช้งาน มีข้อ จำกัด สำหรับข้อโต้แย้งที่ส่งผ่านใน exec หรือไม่? หรือจาก PHP หรือใน Linux shell? ฉันใช้ php 5.4 และ Linux Redhat 7ฉันต้องการเรียกใช้กระบวนการโดยใช้ GNU แบบขนาน แต่เนื่องจาก PHP เป็นเธรดเดียว (มีไลบรารีที่จะส่งผ่านสิ่งนี้ แต่ฉันต้องการหลีกเลี่ยงสิ่งนั้น) บางทีฉันอาจส่งต่อไปยังไฟล์ข้อความและดำเนินการกับสคริปต์ที่ดึงมาจากไฟล์ข้อความนี้ ช่วยด้วย!
** อัปเดต: ขีด จำกัด เครื่องของฉัน: ** #getconf ARG_MAX 2097152 #ulimit -a ขนาดไฟล์หลัก (บล็อก -c) 0 ขนาด seg ข้อมูล (kbytes, -d) ไม่ จำกัด ลำดับความสำคัญของการจัดกำหนดการ (-e) 0 ขนาดไฟล์ (บล็อก -f) ไม่ จำกัด สัญญาณที่รอดำเนินการ (-i) 256634 หน่วยความจำล็อคสูงสุด (kbytes, -l) 64 ขนาดหน่วยความจำสูงสุด (kbytes, -m) ไม่ จำกัด เปิดไฟล์ (-n) 1024 ขนาดท่อ (512 ไบต์, -p) 8 คิวข้อความ POSIX (ไบต์, -q) 819200 ลำดับความสำคัญแบบเรียลไทม์ (-r) 0 ขนาดกองซ้อน (kbytes, -s) 8192 เวลา cpu (วินาที, -t) ไม่ จำกัด กระบวนการผู้ใช้สูงสุด (-u) 4096 หน่วยความจำเสมือน (kbytes, -v) ไม่ จำกัด ล็อคไฟล์ (-x) ไม่ จำกัด
คำตอบ
ในระบบส่วนใหญ่เคอร์เนลจะ จำกัด ขนาดของอาร์กิวเมนต์ไว้ที่execve()syscall (บรรทัดคำสั่ง args + environment vars) บน Linux ขีด จำกัด จะเกี่ยวข้องกับขนาดสแต็กสูงสุดแม้ว่าโดยปกติคุณจะได้รับผลรวมอย่างน้อย 2 MB สำหรับขีด จำกัด ขนาดสแต็กเริ่มต้นที่ 8 MB นอกจากนี้ยัง จำกัดอาร์กิวเมนต์เดียวไว้ที่ 128 kB ดูเช่นมีการขยายชื่อไฟล์สูงสุด (globbing) หรือไม่และถ้าเป็นเช่นนั้นมันคืออะไร? และเพิ่มขีด จำกัด 128KiB สำหรับตัวแปรสภาพแวดล้อมใน Linux
หาก PHP ทำงานsh -c 'command line'เมื่อคุณเรียกexec("command line")ใช้อาร์กิวเมนต์-cอาจเกินขีด จำกัด 128 kB ความจริงที่ว่าบรรทัดคำสั่งถูกแบ่งออกเป็นคำที่แตกต่างกันในภายหลังโดยเชลล์จะไม่ช่วย
เมื่อคุณมีอาร์กิวเมนต์จำนวนมากนี้คุณต้องการส่งต่อไปยัง GNU Parallel ผ่านอินพุตมาตรฐาน (stdin) หรือผ่านไฟล์
ฉันจะทำบางอย่างเช่น (ยังไม่ทดลอง):
$f = popen("parallel","w"); fwrite($f,$commands); close ($f);
ด้วยวิธีนี้คุณอาจสามารถหลีกเลี่ยงไฟล์ชั่วคราวได้
ดังนั้นด้วยความช่วยเหลือของคุณนี่คือทางออกของฉัน: 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 เพื่อให้มีบริบทเพิ่มเติมว่าเกิดอะไรขึ้นฉันสามารถสแกนโฮสต์เกือบ 40.000 แห่งใน 7 ชั่วโมง เว็บเซิร์ฟเวอร์เพิ่มเป้าหมายทั้งหมดลงในไฟล์ในไม่กี่วินาทีและเมื่อ exec ของฉันเปิดใช้กระบวนการพื้นหลังที่ใช้ไม่ต้องรอผลลัพธ์ (เรากำลังส่งออกไปยังไฟล์)
และสคริปต์ check.sh กำลังอัปเดตบันทึกฐานข้อมูล Mariadb สำหรับเป้าหมายเฉพาะในขณะที่ดำเนินการ