Почему Perl не печатает последний текст перед завершением работы?

StackOverflow https://stackoverflow.com/questions/636083

  •  10-07-2019
  •  | 
  •  

Вопрос

Мой код не будет запускать последнюю строку прямо перед " exit; - и я понятия не имею, почему.Я попытался поставить дополнительный printf $fh линия перед exit, но и это не сработало;он не напечатал бы ни одной строки.Все остальное печатается нормально, за исключением последних инструкций печати перед завершением.

Есть какие-нибудь подсказки, почему это происходит?Или, еще лучше, как это исправить или обойти?

    if($i>0 && $i<3)
    {
        printf $fh "Partial match found.\n";
        if($matched_uid){printf $fh "UID #: ".$arguid." exists.\n";}
        if($matched_id){printf $fh "ID #: ".$argid." exists.\n";}
        if($matched_uname){printf $fh "Username: ".$arguname." exists.\n";}
        printf $fh "Aborting."; 
        exit;
    }

Редактировать:
Часть кода, который я скопировал, содержала это

select $fh; $| = 1; #set auto flush

Может быть, именно поэтому мои результаты не смогли быть продублированы....

Это было полезно?

Решение

Попробуйте «Прервать. »

Это похоже на проблему с буферизацией.

Другие советы

Я дал Р.Бемроуз мой голос, но если $fh - это РУЧКА ФАЙЛА возможно, ты тоже захочешь close это до завершения.

Кроме того, вы используете printf ошибочно.printf это нет 'распечатать файл'.его «формат печати».

Для этого последнего примера

  print $fh 'Message' ;  

Это все, что тебе нужно.

printf предназначен для использования таким образом:

printf $fh 'some format %s  and more %s ' ,  $var , $var ; 

или

   printf 'some format %s  and more %s ' ,  $var , $var ; 

и это эквивалентно выполнению

   print $fh sprintf 'format %s more %s' , $var , $var ; 

И из-за этого вы подвергаете ненужному коду риски в случае, если какая-либо из ваших объединенных переменных расширится до содержания в них «%».Пример людей, попавших в эту ловушку, см. Вопрос:308417:Почему мой сценарий Perl удаляет символы из файла?

perldoc -f print

print FILEHANDLE LIST
print LIST
print   Prints a string or a list of strings.

perldoc -f printf

printf FILEHANDLE FORMAT, LIST
printf FORMAT, LIST
      Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", except that "$\" 
      (the output record separator) is not appended

Дальнейшее зондирование

Я продолжаю изучать вашу проблему, потому что не могу добиться выполнения вашего условия «буферизации».Все мои файлы сбрасываются правильно независимо от того, сбрасываю я их или нет.(Перл 5.10).

Вот мой фрагмент кода, который я пытаюсь:

#!/usr/bin/perl 

use strict;
use warnings;


open my $fh , '>' , '/tmp/oo.txt'; 

my $exit_at = int(rand( 200_000 ));
print "$exit_at\n";
sleep 2;
for ( 0 .. ( $exit_at * 2 ) ){ 
    print $fh $_;
    if ( $_ == $exit_at ){
        printf $fh '%n' ; # Bad Code Causes Early Death. 
        printf $fh 'last line';
        exit; 
    }
    if ( $_ % 1000  ){
        print $fh "\n";
    }
}

Я использую ваше неправильное использование printf.Закомментированная строка выдает сообщение об ошибке, поскольку она недействительна, поскольку никто не предоставил параметр «n», и она завершается:

Modification of a read-only value attempted at iotest.pl line 15.

Перед выполнением печати «последней строки» (тоже плохо, но в ней нет символов %, так что все в порядке), исключив «последнюю строку» из выходного файла.

Пожалуйста, исправьте свой printf и используйте вместо него обычный-старый-принт и посмотрите, решит ли это вашу проблему.

Perl буферизует свой вывод.Вы можете отключить автобуферизацию с помощью

local $| = 1;

Редактировать:Я как-то попал!вместо | первый раз...зафиксированный.Понятия не имею, как это произошло, они по разные стороны клавиатуры.

По вопросу о надлежащем использовании print, - ты немного усложняешь себе жизнь.

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

Вот один из способов:

if( $i>0 && $i<3 )
{
    print $fh join "\n", 
        "Partial match found.",
        $matched_uid   ? "UID #: $arguid exists."      : (),
        $matched_id    ? "ID #: $argid exists."        : (),
        $matched_uname ? "Username: $arguname exists." : (),
        "Aborting.",
        ;

    exit;
}

Тот Самый () на стороне false троичного оператора находится пустой список, который исчезнет, когда аргументы для объединения будут сглажены.Если бы я использовал и пустую строку (''), каждый несоответствующий критерий привел бы к появлению дополнительной пустой строки в результатах.

Вы также можете добавить свой собственный перевод строки для каждого элемента, а затем пропустить объединение, если считаете, что это более читабельно:

    print $fh  
        "Partial match found.\n",
        $matched_uid   ? "UID #: $arguid exists.\n" : '',
        ...

Вам нужно добавить завершающий к последнему printf.В противном случае вывод не будет сброшен на консоль.

Либо Дэвид Норман прав, либо проблема где-то в другом.Я только что набрал код внутри блока IF в интерпретаторе Perl, и он напечатал «прерывание». как и ожидалось.(У меня это сработало даже без завершающего символа новой строки.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top