php脚本调用bash脚本时死掉,可能是服务器配置问题

发布于 2024-09-02 16:09:15 字数 3276 浏览 2 评论 0原文

我在调用 Bash 脚本的 PHP 脚本时遇到一些问题......在 PHP 脚本中上传了一个 XML 文件,然后 PHP 脚本调用了一个将文件分成几部分的 Bash 脚本(例如,上传了一个 XML 文件) 30,000 行,因此 Bash 脚本将文件切成 10,000 行的部分,因此将是 3 个文件,每个文件 10,000 行)

文件上传后,Bash 脚本剪切行,但是当 Bash 脚本返回 PHP 脚本时, PHP 脚本终止, &我不知道为什么...我在另一台服务器上测试了脚本,它工作正常...我不相信这是内存问题,也许是处理器问题,我不知道,我不知道该怎么办,可以做什么我愿意??? (我在 PHP 中使用函数 shell_exec 调用 Bash 脚本)

仅当 XML 文件超过 8,000 行时才会发生错误,但如果文件少于 8,000 行,则一切正常(这是相对的,它取决于 XML 文件的数量)数据、字符串、包含每一行的字母)

你能给我什么建议??? (抱歉我的英语不好,我必须多练习xD) 我把代码留在这里

PHP 脚本(最后,在 ?> 之后,有 html 和 javascript 代码,但没有出现,只有 javascript 代码...基本上 html 只是上传文件)


" . date('c') . ": $str
"; $file = fopen("uploadxmltest.debug.txt","a"); fwrite($file,date('c') . ": $str\n"); fclose($file); } try{ if(is_uploaded_file($_FILES['tfile']['tmp_name'])){ debug("step 1: the file was uploaded"); $norg=date('y-m-d')."_".md5(microtime()); $nfle="testfiles/$norg.xml"; $ndir="testfiles/$norg"; $ndir2="testfiles/$norg"; if(move_uploaded_file($_FILES['tfile']['tmp_name'],"$nfle")){ debug("step 2: the file was moved to the directory"); debug("memory_get_usage(): " . memory_get_usage()); debug("memory_get_usage(true): " . memory_get_usage(true)); debug("memory_get_peak_usage(): " . memory_get_peak_usage()); debug("memory_get_peak_usage(true): " . memory_get_peak_usage(true)); $shll=shell_exec("./crm_cutfile_v2.sh \"$nfle\" \"$ndir\" \"$norg\" "); debug("result: $shll"); debug("memory_get_usage(): " . memory_get_usage()); debug("memory_get_usage(true): " . memory_get_usage(true)); debug("memory_get_peak_usage(): " . memory_get_peak_usage()); debug("memory_get_peak_usage(true): " . memory_get_peak_usage(true)); debug("step 3: the file was cutted.
END"); } else{ debug("ERROR: I didnt move the file"); exit(); } } else{ debug("ERROR: I didnt upload the file"); //exit(); } } catch(Exception $e){ debug("Exception: " . $e->getMessage()); exit(); } ?> Test function uploadFile(){ alert("start"); if(document.test.tfile.value==""){ alert("First you have to upload a file"); } else{ document.test.submit(); } }

Bash 脚本与 AWK


#!/bin/bash

#For single messages (one message per contact)
function cutfile(){
 lines=$( cat "$1" | awk 'END {print NR}' )
 fline="$4";

 if [ -d "$2" ]; then
  exsts=1
 else
  mkdir "$2"
 fi

 cp "$1" "$2/datasource.xml"
 cd "$2"

 i=1
 contfile=1
 while [ $i -le $lines ]
 do 
  currentline=$( cat "datasource.xml" | awk -v fl=$i 'NR==fl {print $0}' )

  #creates first file
  if [ $i -eq 1 ]; then
   echo "$fline" >>"$3_1.txt"
  else
   #creates the rest of files when there are more than 10,000 contacts
   rsd=$(( ( $i - 2 ) % 10000 ))
   if [ $rsd -eq 0 ]; then
    echo "" >>"$3_$contfile.txt"
    contfile=$(( $contfile + 1 ))
    echo "$fline" >>"$3_$contfile.txt"
   fi
  fi

  echo "$currentline" >>"$3_$contfile.txt"
  i=$(( $i + 1 )) 
 done

 echo "" >>"$3_$contfile.txt"
 return 1
}


#For multiple messages (one message for all contacts)
function cutfile_multi(){
 return 1
}

cutfile "$1" "$2" "$3" "$4"
echo 1

谢谢!!!! =D

I have some problems with a PHP script that calls a Bash script.... in the PHP script is uploaded a XML file, then the PHP script calls a Bash script that cut the file in portions (for example, is uploaded a XML file of 30,000 lines, so the Bash script cut the file in portions of 10,000 lines, so it will be 3 files of 10,000 each one)

The file is uploaded, the Bash script cut the lines, but when the Bash script returns to the PHP script, the PHP script dies, & I dont know why... I tested the script in another server and it works fine... I dont believe that is a memory problem, maybe it is a processor problem, I dont know, I dont know what to do, what can I do??? (Im using the function shell_exec in PHP to call the Bash script)

The error only happens if the XML file has more than 8,000 lines, but if the file has less then 8,000 everything is ok (this is relative, it depends of the amount of data, of strings, of letters that contains each line)

what can you suggest me??? (sorry for my bad english, I have to practice a lot xD)
I leave the code here

PHP script (at the end, after the ?>, there is html & javascript code, but it doesnt appear, only the javascript code... basically the html is only to upload the file)


" . date('c') . ": $str
"; $file = fopen("uploadxmltest.debug.txt","a"); fwrite($file,date('c') . ": $str\n"); fclose($file); } try{ if(is_uploaded_file($_FILES['tfile']['tmp_name'])){ debug("step 1: the file was uploaded"); $norg=date('y-m-d')."_".md5(microtime()); $nfle="testfiles/$norg.xml"; $ndir="testfiles/$norg"; $ndir2="testfiles/$norg"; if(move_uploaded_file($_FILES['tfile']['tmp_name'],"$nfle")){ debug("step 2: the file was moved to the directory"); debug("memory_get_usage(): " . memory_get_usage()); debug("memory_get_usage(true): " . memory_get_usage(true)); debug("memory_get_peak_usage(): " . memory_get_peak_usage()); debug("memory_get_peak_usage(true): " . memory_get_peak_usage(true)); $shll=shell_exec("./crm_cutfile_v2.sh \"$nfle\" \"$ndir\" \"$norg\" "); debug("result: $shll"); debug("memory_get_usage(): " . memory_get_usage()); debug("memory_get_usage(true): " . memory_get_usage(true)); debug("memory_get_peak_usage(): " . memory_get_peak_usage()); debug("memory_get_peak_usage(true): " . memory_get_peak_usage(true)); debug("step 3: the file was cutted.
END"); } else{ debug("ERROR: I didnt move the file"); exit(); } } else{ debug("ERROR: I didnt upload the file"); //exit(); } } catch(Exception $e){ debug("Exception: " . $e->getMessage()); exit(); } ?> Test function uploadFile(){ alert("start"); if(document.test.tfile.value==""){ alert("First you have to upload a file"); } else{ document.test.submit(); } }

Bash script with AWK


#!/bin/bash

#For single messages (one message per contact)
function cutfile(){
 lines=$( cat "$1" | awk 'END {print NR}' )
 fline="$4";

 if [ -d "$2" ]; then
  exsts=1
 else
  mkdir "$2"
 fi

 cp "$1" "$2/datasource.xml"
 cd "$2"

 i=1
 contfile=1
 while [ $i -le $lines ]
 do 
  currentline=$( cat "datasource.xml" | awk -v fl=$i 'NR==fl {print $0}' )

  #creates first file
  if [ $i -eq 1 ]; then
   echo "$fline" >>"$3_1.txt"
  else
   #creates the rest of files when there are more than 10,000 contacts
   rsd=$(( ( $i - 2 ) % 10000 ))
   if [ $rsd -eq 0 ]; then
    echo "" >>"$3_$contfile.txt"
    contfile=$(( $contfile + 1 ))
    echo "$fline" >>"$3_$contfile.txt"
   fi
  fi

  echo "$currentline" >>"$3_$contfile.txt"
  i=$(( $i + 1 )) 
 done

 echo "" >>"$3_$contfile.txt"
 return 1
}


#For multiple messages (one message for all contacts)
function cutfile_multi(){
 return 1
}

cutfile "$1" "$2" "$3" "$4"
echo 1

thanks!!!!! =D

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合约呢 2024-09-09 16:09:15

您可能应该使用 split 实用程序而不是大部分或全部 Bash 脚本。


这些是对您的代码的一些注释。它确实需要进行一次大修。

要获取文件中的行数:

lines=$( wc -l < "$1" )

您永远不要使用变量exsts。为什么不这样做:

if [ ! -d "$2" ]; then
    mkdir "$2"
fi

为文件中的每一行单独调用 awk 速度非常慢。要么使用一个 AWK 脚本来完成全部或大部分工作,要么使用 while 循环迭代文件中的各行:

while read -r currentline
do
    process_line    # this represents what needs to be done to each line
done < datasource.xml

在 Bash 中,您可以像这样递增一个整数变量:

(( contfile++ ))
(( i++ ))

您的 PHP 脚本正在调用您的只有三个参数的 Bash 脚本。除此之外我并没有真正看过 PHP 脚本。


不过,说真的,请使用split。很简单:

split --lines 10000 --numeric-suffixes --suffix-length 4 datasource.xml "$3_"
for file in "$3_*"
do
    echo "$fline" | cat - "$file" > "$file.txt" && rm "$file"
done

You should probably use the split utility instead of most or all of your Bash script.


These are some comments on your code. It really needs a major overhaul.

To get the number of lines in a file:

lines=$( wc -l < "$1" )

You never use the variable exsts. Why not just do:

if [ ! -d "$2" ]; then
    mkdir "$2"
fi

Calling awk separately for every single line in the file is extremely slow. Either use one AWK script to do all or most of the work or iterate over the lines in your file using a while loop:

while read -r currentline
do
    process_line    # this represents what needs to be done to each line
done < datasource.xml

In Bash you can increment an integer variable like this:

(( contfile++ ))
(( i++ ))

Your PHP script is calling your Bash script with only three arguments. Other than that I didn't really look at the PHP script.


Seriously, though, use split. It's as simple as:

split --lines 10000 --numeric-suffixes --suffix-length 4 datasource.xml "$3_"
for file in "$3_*"
do
    echo "$fline" | cat - "$file" > "$file.txt" && rm "$file"
done
很酷不放纵 2024-09-09 16:09:15

以下是我要查看的一些内容(主要是为了了解有关问题的更多细节):

  • 尝试替换不同的 bash 脚本,一种不执行任何操作,另一种则分割较大的文件。 PHP 脚本在一种或两种情况下都会终止吗?
  • 检查服务器上的权限。脚本和文件是否被授予适当的权限? (尽管这并不能解释为什么小文件可以正常工作。)
  • 检查 PHP 和 Web 服务器错误日志。错误可能出现在此处,而不是出现在浏览器窗口中。 (如果是这样,请将其包含在您的问题中以获得更多帮助。)
  • 因为它似乎与内存有关,您可以尝试增加 PHP 中处理上传内存使用情况的设置,尽管我相信该错误会在上传期间发生,然后才会发生。 bash 脚本调用。

希望这些有所帮助,很抱歉我无法提供更具体的想法。

Here are some things I would look at (mainly to know more specifics about the problem):

  • Try substituting different bash scripts, one that does nothing, and one that splits a file of a large size. Does the PHP script die in one or both cases?
  • Check permissions on the servers. Are the scripts and files being granted the appropriate permissions? (Though this doesn't explain why small files work OK.)
  • Check the PHP and web server error logs. It may be that the error is appearing there rather than in the browser window. (And if so, include it with your question for additional help.)
  • Because it seems related to memory, you could try increasing settings in PHP that deal with memory usage for uploads, though I believe the error would occur during the upload, before the bash script call.

Hope these help, I am sorry I can't offer more specific ideas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文