вывод искажается при параллельном запуске «xargs ls»

Я хочу перечислить все файлы в /usr/ using ls . Я не звоню напрямую, но через xargs . Более того, я использую параметры xargs -L и -P для использования всех моих ядер.

 find /usr/ -type f -print0 | xargs -0 -L16 -P4 ls -lAd | sort -k9 > /tmp/aaa 

вышеуказанная команда работает так, как ожидалось. Это дает хороший результат. Однако, когда я увеличиваю количество строк -L параметра от 16 до 64:

  • Может «найти» команду сохранить время доступа
  • Предоставлять строки, хранящиеся в файле, в виде списка аргументов для команды?
  • Настройка цветов LS с человеко-читаемым скриптом в tcsh
  • Процессы печати, отсортированные по использованию ЦП
  • Понимание вывода ls -l
  • Выполните вывод parse ls с помощью sed, чтобы получить расположение файлов файлов с определенными именами
  •  find /usr/ -type f -print0 | xargs -0 -L64 -P4 ls -lAd | sort -k9 > /tmp/bbb 

    результирующий результат все искажается. Я имею в виду, что вывод больше не начинается на новой строке, новые строки начинаются в середине «предыдущей» строки и все перемешаны:

     -rw-r--r-- 1 root root 5455 Nov 16 2010 /usr/shareonts/X11/encodings/armscii-8.enc.gz -rw-r--r-- 1 root root 1285 May 29 2016-rw-r--r-- 1 root root 6205 May 29 2016 /usr/include/arpa/nameser_compat.h -rw-r--r-- 1 root root 0 Apr 17 20-rw-r--r-- 1 root root 933 Apr 16 2012 /usr/share/icons/nuoveXT2/16x16/actions/address-book-new.png -rw-r--r-- 1 root root 53651 Jun 17 2012-rw-r--r-- 1 root root 7117 May 29 2016 /usr/include/dlfcn.h -rw-r--r-- 1 root root 311 Jun 9 2015-rw-r--r-- 1 root root 1700 Jun 9 2015 /usr/share/cups/templates/de/add-printer.tmpl -rw-r--r-- 1 root root 5157 M1 root root 10620 Jun 14 2012 /usr/lib/perl5/Tk/pTk/tkIntXlibDecls.m -rw-r--r-- 1 root -rwxr-xr-x 1 root root 1829 Jan 22 2013 /usr/lib/emacsen-common/packages/install/dictionaries-common -rw-r--r-- 1 root r-rw-r--r-- 1 root root 1890 Jun 2 2012 /usr/share/perl5/Date/Manip/TZ/afaddi00.pm -rw-r--r-- 1 root root 1104 Jul-rw-r--r-- 1 root root 10268 Jul 27 15:58 /usr/share/perl/5.14.2/B/Debug.pm -rw-r--r-- 1 root root 725 Apr 1-rw-r--r-- 1 root root 883 Apr 1 2012 /usr/share/icons/gnome/16x16/actions/address-book-new.png 

    Забавно, это происходит только при использовании -L64 или больше. Я не вижу этой проблемы с -L16 .

    Кто-нибудь может объяснить, что здесь происходит?

  • Найдите владельца каталога или файла, но верните его только и ничего не сделайте
  • Локальный, обычный файл вызывает зависание `stat` или` ls -l`
  • Найти команду: несколько условий
  • Укажите только размер и имя файла и символические ссылки
  • Улучшите работу find -exec ...
  • git checkout конкретные файлы
  • 2 Solutions collect form web for “вывод искажается при параллельном запуске «xargs ls»”

    Это связано с записью на трубы. С -L16 вы запускаете один процесс для каждых 16 файлов, который производит около тысячи символов, в зависимости от того, как долго имена файлов. С -L64 вас около четырех тысяч. Программа ls почти наверняка использует библиотеку stdio и почти наверняка использует буфер 4kB для вывода, чтобы уменьшить количество вызовов записи.

    Таким образом, find производит загрузку имен файлов, затем (для случая -L64) xargs прерывает их в пакеты из 64 и запускает 4 ls процессы для их обработки. Каждый ls будет генерировать первые 4k вывода и записать его в канал для сортировки. Обратите внимание, что этот 4k обычно не заканчивается символом новой строки. Так скажите, что третий ls получает первый 4kB, первый, и заканчивается

      lrwxrwxrwx 1 root root 6 Oct 21 2013 bzegrep -> bzgrep -rwxr-xr-x 1 root root 4877 Oct 21 2013 bzexe lrwxrwxrwx 1 root root 6 Oct 2 

    а затем первые ls выдает что-то, например

      total 123459 

    то вход для сортировки будет включать в lrwxrwxrwx 1 root root 6 Oct 2total 123459

    В случае -L16 процессы ls будут (обычно) выводить только полный набор результатов за один раз.

    Конечно, для этого случая вы просто тратите время и ресурсы, используя xargs и ls, вы должны просто позволить find выходную информацию, которую он уже имеет, а не запускать дополнительные программы, чтобы снова обнаружить эту информацию.

    GNU Parallel была создана для решения проблемы микширования (время работы 40 секунд):

     find /usr/ -type f -print0 | parallel -0 -L64 -P4 ls -lAd | sort -k9 > /tmp/bbb 

    Он может даже определить количество ядер (время работы 40 секунд):

     find /usr/ -type f -print0 | parallel -0 -L64 ls -lAd | sort -k9 > /tmp/bbb 

    И разделите вход равномерно (время работы 24 секунды):

     find /usr/ -type f -print0 | parallel -0 -X ls -lAd | sort -k9 > /tmp/bbb 
    Linux и Unix - лучшая ОС в мире.