Неверный ли путь к моему текстовому файлу? Переход с Linux на сервер Windows

Я новичок в Perl. Я пытаюсь учиться на основе работы предыдущего человека и таких книг, как Learning Perl и Современный Perl. Я пытаюсь обновить этот сценарий, который интерпретирует данные из HTML-формы и записывает их в текстовый файл, поскольку наша лаборатория заинтересована в том, чтобы снова запустить его. Оригинальный сценарий был написан для использования на сервере Linux, но с тех пор мы перешли с Linux на сервер Windows.

Сервер, к которому у меня нет доступа администратора для просмотра сообщений об ошибках, — это сервер Windows с ActivePerl. У меня возникли трудности с определением эквивалентного пути Windows, чтобы указать Perl-скрипту, куда записывать информацию. Из разговора с администратором кажется, что наша интрасеть отображается на диске E:, хотя это не может быть фатальной ошибкой.

Когда я пытаюсь запустить этот скрипт в браузере после того, как данные были введены в форму, он просто возвращает общий код:

CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers.

Любые советы, документация, учебные пособия приветствуются. Спасибо.

#!C:\perl\bin\perl.exe -w -t

# Good programming practice dictates...
use strict;
use warnings;

# CGI.pm -- makes life easy
#Carp qw(fatalsToBrowser); outputs the error messages to the browser since there is no terminal to output error messages to. Should be removed before script is used in production.
use CGI::Carp qw(fatalsToBrowser) or die "Problems loading CGI.pm";

# Initialize the CGI Interface
my($cgi) = new CGI;

# Print the Header
print $cgi->header();

#The dbmopen call is now de-appreciated. IE: it no longer works
#Kept for archival reasons
#if (! dbmopen(%DB, "/vol/research/docs/old_site_files/eyesignup/data/eyesignup_NEW.dat", 0666))
#   {
#   print "Error -- Cannot open database.\n";
#   exit;
#   }
# Tie is the correct way to do it now. But first we are going to experiment with writing to a flat .txt file.
open (Datastore, '>>',"E:/intranet/sds/research/docs/data.txt") or die "Can't open file: $!";



# Store variables and increment access count for this user
# So param('VARIABLE') is the name of the variables used in the HTML form while $custVARIABLE is the input for the database

my($custFirst) = $cgi->param('firstname');
my($custLast) = $cgi->param('lastname');
my($custGender) = $cgi->param('gender');
my($custAge) = $cgi->param('age');
my($custDiv) = $cgi->param('division');
my($custPhone) = $cgi->param('phone');
my($custEmail) = $cgi->param('email');
my($custEmployee) = $cgi->param('employee');
my($custInternet) = $cgi->param('internet');
my($custwww) = $cgi->param('www');
my($custDemographic) = $cgi->param('demographic');
my($custProjects) = $cgi->param('projectsworked');
my($custExperience) = $cgi->param('experience');
my($custWeekdays) = $cgi->param('Weekdays');

#Kept for archival reasons
#my($custName) = $cgi->param('name');
#my($custGender) = $cgi->param('gender');
#my($custDiv) = $cgi->param('division');
#my($custPhone) = $cgi->param('phone');
#my($custEmail) = $cgi->param('email');
#my($custInternet) = $cgi->param('internet');
#my($custwww) = $cgi->param('www');
#my($custDemographic) = $cgi->param('demographic');
#my($custExperience) = $cgi->param('experience');
#my($custTimes) = $cgi->param('times');
#my($custStudies) = $cgi->param('studies');
#$custTimes =~ s/\r\n/~/g;

#This takes the input and places it into an array, starting with the individual's
@InfoDB = $custFirst."|".$custLast."|".$custGender."|".$custAge."|".$custDiv."|".$custPhone."|".$custEmail."|".$custEmployee."|".$custInternet."|".$custwww."|".$custDemographic."|".$custProjects."|".$custExperience."|".$custWeekdays;
print Datastore (@InfoDB);
print "\n";

#Kept for archivival reasons.
#$DB{$custName} = $custGender."|".$custDiv."|".$custPhone."|".$custEmail."|".$custInternet."|".$custwww."|".$custDemographic."|".$custExperience."|".$custTimes."|".$custStudies;

#Kept for archival reasons. dbmclose is de-appreciated
#dbmclose(%DB);
#Instead use untie. But first we're just going experiment with using a flat storage system.
#untie(%DB);
close (Datastore) or die;

#Now inform the person their data has been saved. This is terribly ancient code so I haven't gotten around to fixing this part yet.
print "Content-type: text/html\n\n";

print "<HTML>
<HEAD>
<TITLE>Thank you!</TITLE>
</HEAD>
<BODY>";

print "<H1><U>Thank You ".$custFirst."\!</U></H1>
<P>We appreciate your assistance.</P>
<HR width=\"75%\">";

print "<P><H3>The following information has been recorded:</H3>
Name: <I>".$custFirst."</I></p><P>
Gender: <i>".$custGender."</i></p><p>
Division: <i>".$custDiv."</i></p><p>
Phone: <i>".$custPhone."</i></p><p>
Email: <i>".$custEmail."</I></p><P>
How often do you use the internet?: <i>".$custInternet."</i></p><p>
How often do you visit the website?: <i>".$custwww."</i></p><p>
Are you familiar with demographic data?: <i>".$custDemographic."</i></p><p>
Do you have work experience in economics, business, or a related field?: <i>".$custExperience."</i></p><p>
Weekdays that you are available: <i>".$custWeekdays."</i></p><p>
";

print "
</BODY>
</HTML>";

Я внес несколько изменений, чтобы компенсировать некоторые ограничения, с которыми я работаю. Например, временно выводить ошибки в браузер, пока я не заработаю. И переход от старого вызова dbmopen (который больше не работает) к хранилищу неструктурированных файлов.


person OneBigNewbie    schedule 05.04.2011    source источник


Ответы (5)


use CGI::Carp qw(fatalsToBrowser) or die "Problems loading CGI.pm"; это ваша проблема.

$ perl -wle 'use CGI::Carp qw(fatalsToBrowser) or die "Problems loading CGI.pm";'
syntax error at -e line 1, near "qw(fatalsToBrowser) or"
Execution of -e aborted due to compilation errors.

Ваша программа умирала во время компиляции, поэтому вы не получили полезной синтаксической ошибки. Обычно вы могли бы видеть это в своих журналах, но вы не можете. or die не нужен (и является синтаксической ошибкой) в операторе use. Уже будет выдавать ошибку.

Вам действительно нужна копия Perl на вашей локальной машине на работе, чтобы тестировать ваши программы. Используйте это как боеприпасы. Если они по-прежнему не позволяют вам работать с инструментами, используйте переносную версию Strawberry Perl, для которой требуется нет установщика.

Вам также необходим доступ к журналам ошибок. Спросите об этом у админов. Возможно, они могут предоставить вам доступ только к вашим журналам, не предоставляя вам полный доступ к серверу.

person Schwern    schedule 05.04.2011
comment
Спасибо, я буду использовать портативную версию Strawberry Perl для тестирования своего скрипта. Это должно быть хорошо, поскольку для установки не требуются права администратора. Моя ситуация немного странная, поскольку меня никогда не нанимали для этого (отсюда мои ограниченные возможности и доступ к таким вещам, как журналы ошибок). Это всего лишь одна из вещей, которые я вынужден делать в качестве дополнительной обязанности. Спасибо! - person OneBigNewbie; 11.04.2011

У вас есть следующие строки:

# Print the Header
print $cgi->header();

и далее вниз:

#Now inform the person their data has been saved. This is terribly ancient code so I haven't gotten around to fixing this part yet. 
print "Content-type: text/html\n\n";

Оба делают одно и то же — вы печатаете один и тот же заголовок типа контента дважды. Вы можете удалить тот или иной вызов print. Также бегло просмотрите ссылки на header() в CGI.pm docs, чтобы узнать, что еще можно сделать. .

person Alex Reynolds    schedule 05.04.2011
comment
Спасибо, кажется, я добавил это во время одной из моих попыток отладки кода (один сайт упомянул, что если заголовок отсутствует, perl будет выводить на терминал). Хотя я пытался удалить один или другой, и он все еще не работает. :( - person OneBigNewbie; 06.04.2011
comment
Это совсем не так. Вы можете запустить сценарий в командной строке, и вы просто получите заголовок, отправленный на стандартный вывод, вместе со всем остальным. Заголовок — это просто текст. Попробуйте устранить неполадки, разделив сценарий на более мелкие части, пока не получите то, что работает. Затем добавьте фрагменты вашего сценария обратно и повторно запустите, пока не найдете источник проблемы. - person Alex Reynolds; 06.04.2011

Есть несколько хороших ресурсов о том, как отлаживать сценарии CGI.pm из командной строки:

Предлагаю вам ознакомиться с этими техниками.

person Jim Garrison    schedule 05.04.2011
comment
Спасибо, у меня нет доступа к ActivePerl или StrawberryPerl на работе (ах... удовольствие от работы в ограниченной среде). Мне придется установить его на свои машины дома и попытаться отладить его дома. Спасибо за ссылки на методики! - person OneBigNewbie; 06.04.2011

Также как грубый удар в темноте:

open (Datastore, '>>',"E:/intranet/sds/research/docs/data.txt") or die "Can't open file: $!";

Я не специалист по Windows, но я думаю, что пути в Windows используют обратные косые черты, вместо косой черты, которую почти все остальные использовали.

В дополнение к исправлению вызова print вы также можете заменить имя пути на:

E:\intranet\sds\research\docs\data.txt
person Alex Reynolds    schedule 05.04.2011
comment
Windows обычно принимает косую черту любого типа. Есть исключения, но проблем с открытием файла быть не должно. Не повредит... кроме того, что придется бежать. - person Schwern; 06.04.2011

Еще одно предложение, которое, вероятно, не имеет никакого отношения к проблеме, а просто вопрос избыточности:

#!C:\perl\bin\perl.exe -w -t

Флаг -w — это то же самое, что:

use warnings;
person Alex Reynolds    schedule 05.04.2011
comment
Не совсем то же самое. use warnings является лексическим, оно применяется только к той области, в которой оно находится (в данном случае к файлу). -w включает предупреждения для всей программы: каждой используемой вами функции и библиотеки. Не помешает включить оба. - person Schwern; 06.04.2011