проверить последний измененный файл в каталоге

Мой скрипт для проверки последнего измененного файла в этом каталоге /var/spool/gammu/inbox/

#!/usr/bin/perl -w
use strict;
use warnings;
chomp (my $dirname ='/var/spool/gammu/inbox/');
my $newest_file = do {
opendir my $dh, $dirname or die "Could not open '$dirname' for reading: $!\n";
my @by_age  = sort { -M $a <=> -M $b } grep -f, readdir ($dh);
$by_age[0];
};

open my $file, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
my @rows = <$file>;
close ($file);
print "@rows\n";

Я собираюсь:

Использование неинициализированного значения $newest_file при открытии в ./checken.pl, строка 16.

Использование неинициализированного значения $newest_file в конкатенации (.) или строки в ./checken.pl, строка 16.

Не удалось открыть "" для ввода: Datei oder Verzeichnis nicht gefunden at ./checken.pl строка 16.


person perlfg    schedule 11.04.2016    source источник


Ответы (2)


Я предлагаю вам предварительно указать имя каталога перед файлом (чтобы указать абсолютный путь), используя map, а затем передать его grep.

Это должно выглядеть так, как показано ниже:

my @by_age  = sort {-M $a <=> -M $b} grep {-f $_} map {"$dirname/$_"} readdir ($dh);
person Arunesh Singh    schedule 11.04.2016
comment
Как я могу запустить этот скрипт с помощью while или for. каждый раз скрипт проверяет, есть ли у меня новый файл. - person perlfg; 11.04.2016
comment
оберните его под while(1) { sleep(your seconds)}. - person Arunesh Singh; 11.04.2016
comment
скрипт проверяет каждый раз каталог и должен давать мне ответ только при создании нового файла. - person perlfg; 11.04.2016
comment
Тогда, вероятно, вам следует взглянуть на File::Modified и File::Monitor - person Arunesh Singh; 11.04.2016
comment
@perlfg: Вы еще не приняли ни одного ответа ни на один из ваших вопросов. Пожалуйста, проверьте это: meta.stackexchange. ком/вопросы/5234/ - person Chankey Pathak; 20.09.2016

Возможно, я недостаточно подчеркнул это в моем решении вашего предыдущего вопроса. Я написал

Если вы хотите сделать это для каталога, отличного от cwd, то, вероятно, проще всего просто chdir в него и использовать этот код, чем пытаться opendir в определенный каталог, так как тогда вам придется построить полный путь к каждому файлу перед вы можете использовать -M

Проблема в том, что данные, возвращаемые readdir, представляют собой просто имя файла без какой-либо информации о пути, и если файл находится в каталоге, отличном от текущего рабочего каталога, он не будет найден без добавления информации о пути.

Если вы сначала просто chdir зайдете в каталог, все будет работать нормально. Вот приведенная в порядок версия вашего кода

#!/usr/bin/perl

use strict;
use warnings;

chomp(my $dirname = "/var/spool/gammu/inbox/");
chdir $dirname or die qq{Unable to chdir to "$dirname": $!};

my $newest_file = do {
    opendir my $dh, '.' or die "Could not open '$dirname' for reading: $!\n";
    my @by_age  = sort { -M $a <=> -M $b } grep -f, readdir ($dh);
    $by_age[0];
};

open my $file, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
print while <$file>;

Или, если у вас есть причина избегать изменения каталога в вашей программе (изменение не будет отражено в вашей оболочке после выхода из программы), вам следует использовать rel2abs из File::Spec::Functions для построения полного пути к файлу перед работой с ним.

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions 'rel2abs';

chomp(my $dirname = "/var/spool/gammu/inbox/");

my $newest_file = do {
    opendir my $dh, '.' or die "Could not open '$dirname' for reading: $!\n";
    my @files = map { rel2abs($_, $dirname) } grep -f, readdir ($dh);
    my @by_age  = sort { -M $a <=> -M $b } @files;
    $by_age[0];
};

open my $file, '<', $newest_file or die qq{Unable to open "$newest_file" for input: $!};
print while <$file>;

Некоторые другие моменты

  • use warnings превосходит -w в командной строке. Вы не должны использовать оба

  • Лучше избегать чтения всего файла в память, если вам это не нужно. Файл можно читать и печатать по одной строке за раз

person Borodin    schedule 11.04.2016
comment
Спасибо :)))))))))))) - person perlfg; 13.04.2016