никого не удивил, используя timeout
timeout 5 ping -c 3 somehost
Это не будет работать для каждого примера использования, но если вы имеете дело с простым скриптом, это
Также доступен как gtimeout в coreutils через homebrew
для пользователей Mac.
Вашим путем является "правильный" путь при необходимости в отсортированном списке (и не только первое, см. ответ Brian для этого). Если Вы не представляете себе писать тот код сами, используйте это
use File::DirList;
my @list = File::DirList::list('.', 'M');
Лично я не пошел бы с ls -t
метод - который включает разветвление другой программы и это не портативно. Едва, что я назвал бы "изящным"!
Относительно кодированного решения руки решения rjray я изменил бы его немного:
opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
my @files = map { [ stat "$DIR/$_", $_ ] } grep(! /^\.\.?$/, readdir($DH));
closedir($DH);
sub rev_by_date { $b->[9] <=> $a->[9] }
my @sorted_files = sort rev_by_date @files;
После этого @sorted_files
содержит отсортированный список, где 0th элемент является новейшим файлом, и каждый элемент сам содержит ссылку на результаты stat
, с самим именем файла в последнем элементе:
my @newest = @{$sorted_files[0]};
my $name = pop(@newest);
Преимущество этого состоит в том, что легче изменить метод сортировки позже при желании.
Править: вот является более легкое к чтению (но дольше) версией сканирования каталога, которое также гарантирует, что только простые файлы добавляются к списку:
my @files;
opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
while (defined (my $file = readdir($DH))) {
my $path = $DIR . '/' . $file;
next unless (-f $path); # ignore non-files - automatically does . and ..
push(@files, [ stat(_), $path ]); # re-uses the stat results from '-f'
}
closedir($DH);
NB: тест для defined()
на результате readdir()
то, потому что файл, названный '0', заставил бы цикл перестать работать, если Вы только тестируете на if (my $file = readdir($DH))
Вы не должны сохранять все время изменения и имена файлов в списке, и Вы, вероятно, не были должны. Все, что необходимо сделать, посмотреть на один файл и видеть, является ли это более старым, чем самое старое, Вы ранее видели:
{
opendir my $dh, $dir or die "Could not open $dir: $!";
my( $newest_name, $newest_time ) = ( undef, 2**31 -1 );
while( defined( my $file = readdir( $dh ) ) ) {
my $path = File::Spec->catfile( $dir, $file );
next if -d $path; # skip directories, or anything else you like
( $newest_name, $newest_time ) = ( $file, -M _ ) if( -M $path < $newest_time );
}
print "Newest file is $newest_name\n";
}
Вы могли попытаться использовать оболочку ls
команда:
@list = `ls -t`;
$newest = $list[0];
Принятие Вас знает $DIR
Вы хотите заглянуть:
opendir(my $DH, $DIR) or die "Error opening $DIR: $!";
my %files = map { $_ => (stat("$DIR/$_"))[9] } grep(! /^\.\.?$/, readdir($DH));
closedir($DH);
my @sorted_files = sort { $files{$b} <=> $files{$a} } (keys %files);
# $sorted_files[0] is the most-recently modified. If it isn't the actual
# file-of-interest, you can iterate through @sorted_files until you find
# the interesting file(s).
grep
это переносится readdir
отфильтровывает "." и ".." специальные файлы в UNIX (-выход) файловая система.
Если Вы не можете позволить ls
, делают сортировка для Вас как @Nathan предлагает, то можно оптимизировать процесс, только сохранив новейшее время изменения и связанное имя файла замеченными к настоящему времени и заменить ее каждый раз, когда Вы находите более новый файл в каталоге. Никакая потребность сохранить любые файлы вокруг этого, которое Вы знаете, является более старой, чем новейшее, которое Вы видели до сих пор и конечно никакая потребность отсортировать их, так как можно обнаружить, который является новейшим при чтении из каталога.