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

时间:2010-05-21 21:42:33

标签: php apache bash awk

我在调用Bash脚本的PHP脚本中遇到一些问题....在PHP脚本中上传了一个XML文件,然后PHP脚本调用了一个Bash脚本,该脚本分割文件(例如,上传一个30,000行的XML文件,因此Bash脚本以10,000行的部分剪切文件,因此每个文件将有3个文件,每个文件为10,000个。

文件上传,Bash脚本剪切了行,但是当Bash脚本返回到PHP脚本时,PHP脚本就会死掉,&我不知道为什么......我在另一台服务器上测试了脚本,它运行正常...我不相信这是一个内存问题,也许这是一个处理器问题,我不知道,我不知道该怎么做,什么可以我做??? (我使用PHP中的函数shell_exec来调用Bash脚本)

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

你能建议我什么? (抱歉我的英语不好,我必须练习很多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(); } }

使用AWK的Bash脚本


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

2 个答案:

答案 0 :(得分:1)

您应该使用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

答案 1 :(得分:0)

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

  • 尝试替换不同的bash脚本,一个什么都不做,一个分割大文件的脚本。 PHP脚本是否会在一个或两个案例中死亡?
  • 检查服务器的权限。脚本和文件是否被授予适当的权限? (虽然这并不能解释为什么小文件可以正常工作。)
  • 检查PHP和Web服务器错误日志。可能是错误出现在那里而不是在浏览器窗口中。 (如果是这样,请将其与您的问题一起提供以获得更多帮助。)
  • 因为它似乎与内存有关,所以你可以尝试在PHP中增加处理上传内存使用量的设置,不过我相信在bash脚本调用之前上传过程中会出现错误。

希望这些帮助,对不起,我不能提供更具体的想法。