我在调用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
答案 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)
以下是我要看的一些内容(主要是了解有关问题的更多细节):
希望这些帮助,对不起,我不能提供更具体的想法。