PHP скрипт умирает при вызове bash скрипта, возможно проблема в настройке сервера - PullRequest
2 голосов
/ 22 мая 2010

У меня есть некоторые проблемы со скриптом PHP, который вызывает скрипт Bash .... в скрипт PHP загружается файл XML, затем скрипт PHP вызывает скрипт Bash, который разрезает файл на части (например, загружаетсяXML-файл длиной 30 000 строк, поэтому сценарий Bash разрезает файл на части по 10 000 строк, поэтому он будет состоять из 3 файлов по 10 000 каждый)

Файл загружен, сценарий Bash разрезает строки, нокогда сценарий Bash возвращается к сценарию PHP, сценарий PHP умирает, и я не знаю, почему ... Я протестировал сценарий на другом сервере, и он работает нормально ... Я не верю, что это проблема с памятью, может быть, этопроблема с процессором, я не знаю, я не знаю, что делать, что я могу сделать ???(Я использую функцию shell_exec в PHP для вызова скрипта Bash)

Ошибка возникает только в том случае, если файл XML содержит более 8 000 строк, но если в файле менее 8 000, все в порядке (это относительно,это зависит от количества данных, строк, букв, содержащих каждую строку)

что вы можете мне предложить ???(извините за мой плохой английский, я должен много практиковаться xD) Я оставляю код здесь

PHP-скрипт (в конце, после?>, есть html & javascript код, но он не появляется,только код JavaScript ... в основном HTML только для загрузки файла)


" . date('c') . ": $str<br>";
 $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. <br>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

Ответы [ 2 ]

1 голос
/ 22 мая 2010

Вы, вероятно, должны использовать утилиту 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
0 голосов
/ 22 мая 2010

Вот несколько вещей, на которые я хотел бы взглянуть (в основном, чтобы узнать больше о проблеме):

  • Попробуйте заменить различные скрипты bash: один, который ничего не делает, и тот, который разбивает файл большого размера. Умирает ли скрипт PHP в одном или обоих случаях?
  • Проверка разрешений на серверах. Предоставляются ли сценарии и файлы соответствующие разрешения? (Хотя это не объясняет, почему небольшие файлы работают нормально.)
  • Проверьте журналы ошибок PHP и веб-сервера. Может быть, ошибка появляется там, а не в окне браузера. (И если да, включите его в свой вопрос для получения дополнительной помощи.)
  • Поскольку это, похоже, связано с памятью, вы можете попробовать увеличить настройки в PHP, связанные с использованием памяти для выгрузки, хотя я полагаю, что ошибка произойдет во время выгрузки до вызова скрипта bash.

Надеюсь, что это поможет, извините, я не могу предложить более конкретные идеи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...