LINUX.ORG.RU

find | wc -l нестабильно работает

 ,


0

2

Столкнулся вчера с таким явлением. В скрипте есть в том числе подсчет количества файлов в файлообменнике. Естественно, использую связку find | wc -l До вчерашнего вечера все работало как часы. Явление в том, что через несколько секунд может безрезультатно висеть сколько угодно. При этом вначале find и wc появляются вверху top-а, но потом там исчезают и обнаруживаются только по ps aux. Вероятно, без признаков явной активности.

Успешно подсчет идет в 1/3 случаев. Хотя если запускать find без конвейера, то отрабатывается всегда.

В каталоге, который надо посчитать, 890 тысяч с лишним файлов. Но вряд ли это причина. На чем застревает, не понять. Каталог с кириллическими именами файлов.

Кстати, связка find | wc -l отрабатывается довольно быстро, особенно если запускается повторно, я так понимаю, где-то есть индексация?


Ну натрави strace и посмотри в чем дело. Но мне кажется это дико неэффективно гонять имена файлов в таком количестве по пайпам беcцельно.

Вот прога https://github.com/ChristopherSchultz/fast-file-count/blob/master/dircnt.c хотя можно было бы обойтись без рекурсии.

Ну или df -i . лол

pawnhearts ★★★★★ ()
Последнее исправление: pawnhearts (всего исправлений: 2)
Ответ на: комментарий от pawnhearts

pawnhearts Это еще что, эта директория вложенная, а во всем родительском каталоге больше миллиона файлов. И все в нем считалось. Что теперь не нравится, непонятно. Попробую strace , спасибо. Контролировать одновременно find и wc получится?

DrBim ()
Последнее исправление: DrBim (всего исправлений: 2)
Ответ на: комментарий от DrBim

Контролировать одновременно find и wc получится?

Можно каждый вызвать в его собственном strace или же завернуть в шелл: strace sh -c "find | wc -l". Ну и man strace посмотреть на предмет игнора/не игнора детей.

legolegs ★★★★★ ()

можно попробовать еще использовать find -printf . | wc -c или разделить процессы и посмотреть, что проиходит, когда wc работает, если find отрабатывает всегда - find > /tmp/find; wc -l < /tmp/find

keir ★★ ()
Последнее исправление: keir (всего исправлений: 1)
Ответ на: комментарий от keir

В общем, попробовал я find -printf . | wc -c Из командной строки все работало. И тут я опять засунул в тестовый скриптик, где присваиваю вывод конвейера переменной, ну вот так count_files=$(find /path -not -path «/path_for_exclude/*» -type f -printf .| wc -c)

echo $count_files

И началась та же история. Висит. Запускаю уже просто из командной строки find /path -not -path «/path_for_exclude/*» -type f -printf .| wc -c

и в ps

root хххх 0.0 0.0 12668 1456 pts/2 D+ 14:54 0:00 find …

root уууу 0.0 0.0 6574 688 pts/2 S+ 14:54 0:00 wc -c

Process State Codes

D - Uninterruptible sleep

S - Interruptible sleep (waiting for an event to complete)

Как это можно объяснить?

Конечно, можно предварительно писать в файл, но он получится слишком большой (надо бы как-то имена найденных сокращать).

Еще есть ls -A , или вообще считать иноды, но это же ………. что происходит?

DrBim ()
Последнее исправление: DrBim (всего исправлений: 2)
Ответ на: комментарий от futurama

А почему тогда снова начинает работать : я выбрал другой каталог для подсчета (выполняю сразу из командной строки, не из скрипта), работает. Теперь снова выполняю подсчет в проблемной директории - и чудо, снова пашет.

Проблема начинается только после того, как эта конвейерная команда выполняется из-под bash скрипта. После «сброса ошибки» выполнением подсчета в другой директории, снова подсчет работает в командной строке.

DrBim ()

Если у тебя find висит с Uninterruptible sleep, то реально траблы с fs. Посмотри системный лог, может ядро ругается на ошибки, посмотри смарт дисков, поставь какой-нибудь atop и посмотри загрузку дисков.

У тебя дисковые операции кешируются в память. Поэтому, скорее всего, после того, как find потупит в скрипте, он не потупит в консоли.

Подожди пару часов и без запуска скрипта, запусти find в консоле. Скорее всего, тупняк повторится.

После этого станет понятно что делать.

anonymous ()
Ответ на: комментарий от futurama

, anonymous (02.12.19 18:02:45)

Да да, по-всему, есть в фс траблы. Я это вижу по тому, как появляются в топ процессов обращения юзеров smbd - периодически вижу, как секунды на две-три появляются. А это всё-таки аппаратный raid 50 ! Чтение или даже записи какого то там Вордового документа несколько мегабайт не должно так выглядеть. Походу, надо перезагружать в выхи сервак с проверкой фс. Его ставили до меня, и система вместе с данными на одном райде. Хорошо я хоть начал архивы делать. Собственно, скрипт в т.ч. и выполняет эти подсчёты в ходе архивации.

Буду переустанавливать сервак, надо увеличивать ёмкость хранилища, и думаю разделить, систему на ssd, а своп и данные на lvm на райде. Вот только нормально на сервак будет обычная ssd?

DrBim ()
Последнее исправление: DrBim (всего исправлений: 2)
Ответ на: комментарий от DrBim

Конечно, можно предварительно писать в файл, но он получится слишком большой (надо бы как-то имена найденных сокращать).

find -printf . , если его вывод сохранять в файл, запишет в него только точки, по одной на каждый найденный файл. А wc -c считает кол-во байт.

keir ★★ ()