У меня есть каталог с большим количеством файлов.
./I_am_a_dir_with_many_subdirs/
Внутри скрипта я бы хотел найти в нем все подкаталоги, отсортировать их и вывести в массив bash. Итак, я делаю:
SubdirsArray=(`find ./I_am_a_dir_with_many_subdirs/ -maxdepth 2 -mindepth 2 -type d | sort`)
Выполняя скрипт, я получаю следующие сообщения об ошибках:
sort: write failed: standard output: Broken pipe
sort: write error
Как объясняется в этом посте : вероятно, sort
выполняет и закрывает канал перед find
завершением записи в него. Таким образом, команда write (), инициированная find
EPIPE, получает ошибку «Broken pipe», ОС отправляет find
SIGPIPE. Прежде чем SIGPIPE достигает find
, он печатает сообщение об ошибке, затем получает SIGPIPE и умирает.
Вопросов:
Итак, что
SubdirsArray
содержит мой ? Субдиры, которыеfind
нашли, ноsort
оставили несортированными?Если так, то как быть с этой проблемой с сломанными трубами? Заставить find записать его результаты во временный файл, а затем заставить sort прочитать его?
Я не понимаю, почему «это также не о чем беспокоиться», если это происходит в неинтерактивной оболочке: почему? My
SubdirsArray
содержит что-то несортированное и далее в скрипте, я предполагаю, что его элементы отсортированы ?!Я получаю два сообщения об ошибках:
sort: write failed: standard output: Broken pipe sort: write error
В этой теме предполагается, что sort
во временной директории недостаточно места для сортировки всех входных данных. Но разве это не значит, что этот сорт получил что-то от find?!? Я в замешательстве ... В любом случае, я пытался использовать
SubdirsArray=(`find ./I_am_a_dir_with_many_subdirs/ -maxdepth 2 -mindepth 2 -type d | sort -T /home/temp_dir`)
но это не помогло
PS
Я не уверен, важно ли это, но я использую find|sort
в многопроцессорном сценарии: несколько процессоров одновременно выполняют одну и ту же команду в подоболочках.
sort
ничего не может сделать, прежде чем он прочитает ввод полностью, и, кроме того, если бы онsort
заканчивался преждевременно, он быfind
сообщал о сломанной трубе, а неsort
. Ошибка в другой теме, которую вы упоминаете, выглядит совсем иначе и действительно отличается.Ответы:
Проблема не между
find
аsort
.sort
Имеет проблемы с выходом , а это значит , оболочка не хочет читать длинный список в переменной.Вам придется обрабатывать ввод с помощью
while read
…, сохраняя его во временном файле, если он вам нужен более одного раза. С дополнительным преимуществом, это разделяется только на новую строку, поэтому он правильно обрабатывает имена файлов с пробелами, которых нет в подходе backtick.К сожалению, вы не говорите, как вы хотите использовать результат, я не могу сказать вам, как именно переписать его.
Обратите внимание, что массивы не являются частью спецификации оболочки POSIX, и есть оболочки, которые заметно быстрее, чем bash, но не имеют их. Вот почему многие люди, включая меня, часто избегают использовать их в сценариях.
источник
SubdirsArray
для цикла. Итак, я буду реализовывать ваше решение, как:find ./I_am_a_dir_with_many_subdirs/ -maxdepth 2 -mindepth 2 -type d | sort > temp.txt; while read Subdir; do myFunction $Subdir; done; rm temp.txt
В конце я хотел бы обратитьсяmyFunction
ко всемSubdirs
. Чтобы сделать это быстрее, я пытаюсь распараллелить мой код и использоватьN
подоболочки сwait
. Каждый подоболочек должен занимать только часть Subdirs. Я не хотел отправлять длинный массив подкаталогов, которые он должен обрабатывать для каждой подоболочки, но первый / последний индексSubdirsArray
.find ./I_am_a_dir_with_many_subdirs/ -maxdepth 2 -mindepth 2 -type d | sort > temp.txt; while read Subdir; do myFunction $Subdir; done
<"temp.txt"; rm temp.txt
?read
просто читает со стандартного ввода.<(find ... | sort)
.