Perl CGI-скрипт неправильно читает содержимое текстового файла с помощью backsla sh - PullRequest
1 голос
/ 06 марта 2020

У меня есть простой текстовый файл со строками, содержащими backsla sh (\ что-то). Читая его в сценариях Perl в командной строке, я получаю текстовые строки в точности так, как они есть в файле. Когда EXACT SAME строки кода копируются и вставляются в CGI-скрипт, содержимое текстового файла читается по-разному, добавляя еще одну backsla sh для каждой backsla sh. Я потратил два дня на поиск по различным форумам (StackOverflow, PerlMonks и др. c.), Но не смог найти вероятную причину. Ниже приведен код и текстовый файл. Любая помощь очень ценится.

**~/tests/backslash> cat /home/user1/tests/backslash/pattern.txt**
more LaTex formatted strings.
\frac{a}{b} = \frac{5}{7}
**~/tests/backslash>  cat test.pl**
my $file = "/home/user1/tests/backslash/pattern.txt";
print STDERR "Attempting to open $file and read the last line...\n";
open(FH, "< $file") or die "ERROR: can't open $file: $!";
my @lines = <FH>;
close(FH);
my $myExpression = $lines[scalar(@lines) - 1];
chomp($myExpression);
print STDERR 'Expr: [' . $myExpression . "]\n";
my $retString = qq{{ "result" : "$myExpression" }};
print STDERR $retString . "\n";
**~/tests/backslash> ./test.pl**
Attempting to open /home/user1/tests/backslash/pattern.txt and read the last line...
Expr: [\frac{a}{b} = \frac{5}{7}]
{ "result" : "\frac{a}{b} = \frac{5}{7}" }
**~/tests/backslash>**

Точно такой же код в CGI-скрипте дает следующий вывод:

Output from CGI script Я разбил строку на массив и исследовал каждый символ (в скрипте CGI), который имеет две обратные косые черты перед 'fra c'. Самосвал также подтверждает это. Я попытался заменить две обратные косые черты на '\', но и это не увенчалось успехом. Я столкнулся с множеством других проблем, связанных с пониманием и устранением этой проблемы (например, сценарий CGI не смог открыть один и тот же текстовый файл из / tmp [файл не найден], заменив две обратные косые черты на \ различными способами, но с ошибками синтаксиса, значения переменных становятся неожиданные символы при замене, и т. д. c., но я сосредоточился на основной проблеме обратной косой черты в этом вопросе.) Я на всякий случай сделал все классы 'use' одинаковыми в сценарии командной строки и CGI, даже если Сценарий командной строки не использует CGI, JSON, et c.

Я озадачен, почему точно такой же код Perl ведет себя по-разному в cgi-bin. Любая помощь, предложение, указатели или обсуждения по этому вопросу приветствуется.

My environment:
Suse Linux 13.1
Perl 5.18.1
Apache 2.4.6
Bash 4.2.53

Ответы [ 2 ]

0 голосов
/ 09 марта 2020

Кажется, я понял, где проблема. Это было в MathJax, где он принимает строку LaTex и выполняет рендеринг. Он продолжал отображать строку с обратной косой чертой, поэтому я проследил, откуда взялись двойные обратные косые черты, и обнаружил их в журналах http. Любая печать в файлах также приводила к выходу. При запуске сценария в командной строке он выводится на терминал, поэтому обратные косые черты не экранируются. При работе в cgi-bin невозможно увидеть текущую строку без экранирования. Разделение строки на массив и печать символов по отдельности не имеет значения. Сравнение элементов массива с кавычками q | \ | также подлежит экранированию / интерполяции. Поэтому я не мог подтвердить это любым другим способом. Наконец, после исправления конфигурации MathJax, он правильно отобразил строку. Я оставляю этот вопрос и отвечаю, надеясь, что это сэкономит время для кого-то. Спасибо всем за чтение, комментирование и ответы.

0 голосов
/ 06 марта 2020

Пожалуйста, посмотрите, будет ли более подходящим следующий стиль кодирования

use strict;
use warnings;
use feature 'say';

my $file = '/home/user1/tests/backslash/pattern.txt';

say STDERR "Attempting to open $file and read the last line...";

open my $fh, '<',  $file
    or die "ERROR: can't open $file: $!";

my @lines = <$fh>;

close(FH);

my $myExpression = pop @lines;

chomp($myExpression);

say STDERR "Expr: [$myExpression]";

my $retString = qq{{ "result" : "$myExpression" }};

say STDERR $retString;

ПРИМЕЧАНИЕ: perl имеет оператор pop для извлечения последнего элемента массива

ПРИМЕЧАНИЕ: строка в двойных кавычках предполагает интерполяцию переменных, и ее следует использовать соответствующим образом - если в строке нет переменных, то, вероятно, двойные кавычки не на месте

ПРИМЕЧАНИЕ: бесплатная книга Современный Perl доступен онлайн - см. «Вход и выход» стр. 138

ПРИМЕЧАНИЕ: use strict; use warnings позволяет избежать многих подводных камней

...