2

У меня есть каталог с большим количеством файлов.

./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 и умирает.

Вопросы:

  1. Итак, что же содержит мой SubdirsArray ? Субдиры, которые find найдены, но sort оставлена несортированной?

  2. Если так, то как быть с этой проблемой с сломанными трубами? Заставить find записать результаты во временный файл, а затем заставить sort прочитать его?

    Я не понимаю, почему «это тоже не о чем беспокоиться», если это происходит в неинтерактивной оболочке: почему? Мой SubdirsArray содержит что-то несортированное и далее в скрипте, я предполагаю, что его элементы отсортированы ?!

  3. Я получаю два сообщения об ошибках:

    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 в многопроцессорном скрипте: несколько процессоров одновременно выполняют одну и ту же команду в подоболочках.

1 ответ1

2
sort: write failed: standard output: Broken pipe

Проблема не между find и sort . У sort есть проблема с выводом, что означает, что оболочка не хочет читать как длинный список в переменной.

Вам придется обрабатывать ввод с помощью while read …, сохраняя его во временном файле, если он вам нужен более одного раза. С дополнительным преимуществом, это разделяется только на новую строку, поэтому он правильно обрабатывает имена файлов с пробелами, которых нет в подходе backtick.

К сожалению, вы не говорите, как вы хотите использовать результат, я не могу сказать вам, как именно переписать его.

Обратите внимание, что массивы не являются частью спецификации оболочки POSIX, и есть оболочки, которые заметно быстрее, чем bash, но не имеют их. Вот почему многие люди, включая меня, часто избегают использовать их в сценариях.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .