Найдите последние версии нескольких файлов в нескольких каталогах

[

] Из случайного обзора источника видно, что автор(ы) слишком усердно использовали []set_nonblock[] в []sslh-select.c[].[

] [

] Если пометить каждый сокет (как он есть) как неблокирующий, то цикл [

] [

while(1) {
    select(… a bunch of non-blocking sockets …);
}

] [

] вокруг линии 230 в связанном файле становится занят-ожиданием. То есть, даже если нет доступных для чтения данных ни в одном из сокетов, select возвращается мгновенно, а затем снова вызывается немедленно. Это довольно ресурсоемкий процессор.[

] [

]Автор близко подошел к тому, чтобы сделать это правильно, с некоторым условным использованием аргумента []timeout[] для []select[], но это не имеет никакого эффекта, если все равно все установлено в неблокирующее состояние.[

] [

]Я не профилировал []sslh[], что является лучшим способом подтвердить, что это реальная причина.[

].

1
20.12.2014, 14:58
2 ответа

Вы на правильном пути с вашим выбором инструментов:

  • ls -t - это хороший способ сортировки файлов по времени, так что вы можете выбрать последний
  • find - это правильный инструмент для поиска файлов, соответствующих некоторому шаблону в каталогах и подкаталогах

Коварная часть, конечно же, заключается в том, что вам нужна какая-то группировка по именам файлов, и выберите последний файл в каждой группе. Из-за этого требования, Думаю, тебе нужна петля, где вы проводите итерацию по каждому имени целевого файла, чтобы найти его последнюю версию.

Предположим, что файлы находятся в $dir1, $dir2 или $dir3, можно написать функцию для поиска последней версии какого-нибудь паттерна, например:

find_latest() {
    pattern=$1
    ls -t "$dir1/$pattern" "$dir2/$pattern" "$dir3/$pattern" | head -n 1
}

Тогда скажем, есть ли у вас паттерны access.log, error.log, x*, то их можно обвести таким образом, например:

for pattern in access.log error.log 'x*'; do
    latest=$(find_latest 'a*')
    echo $latest
done

Если приведенное выше предположение не верно, и файлы могут находиться в поддиректориях $dir1, $dir2 или $dir3, тогда вам нужно использовать find, это становится немного сложнее:

find_latest() {
    pattern=$1
    find "$dir1" "$dir2" "$dir3" -name "$pattern" -print0 | xargs -0 ls -t | head -n 1
}

Есть небольшое предостережение: если путь содержит символы новой строки, эта функция не будет работать хорошо, так как на шаге head -n 1 после новой строки будет отрублена часть пути. Скрещиваю пальцы, что у вас нет таких путей ;-)

.
2
27.01.2020, 23:37

Вы можете сделать это с PAX :

pax -wrtvZs"|.*/||p" ./DIR[123] "$PWD"

Так что я постараюсь сломать его аргументом:

  • -WR - это W Rite и r r EAD, и вместе они означают PAX , должны копировать файлы, а не архивирование. Вы также можете подготовиться к копии и просто создавать жесткиенки вместо этого с -L .

  • -T - это сбрасывает все время доступа к файлу в состояние, которое они имели до PAX , прочитайте их, чтобы проверить их метаданные.

  • -V - работает добросовестно.

  • -Z - не сравнивает время мода исходных файлов, пока все возможные замены имени завершены.

    • Это это (и следующая вещь) , которые делают это так просто. Без этого - и вероятно, проблема, которую вы будете иметь в другом месте - это то, что dir1 / filea и dir2 / filea - это разные файлы, даже если они имеют базенное значение. И поэтому они никогда не сравниваются без этого и ...
  • --s - замена и замена порций имени файла со стандартом SED Regexp.

    • Здесь я просто уменьшаю все порции каждого файла в свои базовые имена, и поэтому --z применяется к все FLEAEA S и только новейшее скопировано в «$ PWD» .

Я использовал следующий тест для проверки всего этого:

for d in DIR3 DIR1 DIR2
do  cd ~; mkdir -p "$d"; cd "$d"
    sleep 90; touch FILEB FILEA
done; cd ~

... который получает тестовый набор. Вот полученные времена мода:

ls -l ./DIR[123]/FILE[AB]                                
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:28 ./DIR1/FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:28 ./DIR1/FILEB
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./DIR2/FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./DIR2/FILEB
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:26 ./DIR3/FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:26 ./DIR3/FILEB

и, так, когда я бегу:

pax -wrtvZs"|.*/||p" ./DIR[123] "$PWD"
ls -l ./FILE[AB]

... Вывод ...

./DIR1/FILEA >> FILEA
/home/mikeserv/FILEA
./DIR1/FILEB >> FILEB
/home/mikeserv/FILEB
./DIR2/FILEA >> FILEA
/home/mikeserv/FILEA
./DIR2/FILEB >> FILEB
/home/mikeserv/FILEB
./DIR3/FILEA >> FILEA
./DIR3/FILEB >> FILEB

-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./FILEB

Вы можете видеть, что это произошло. Когда -S -S ||| P Изменяет имя файла P модификатор печатает сообщение STDERR . Таким образом, мы видим файлы DIR1 , которые будут оценены в первую очередь - и скопированы в $ PWD , и следующие файлы Dir2 получают ту же обработку - но DIR3 Файлы не скопированы, потому что $ pwd / file [ab] теперь новее, чем они сейчас.

0
27.01.2020, 23:37

Теги

Похожие вопросы