Быстрая команда ls - PullRequest
       97

Быстрая команда ls

36 голосов
/ 02 сентября 2008

Мне нужно получить список каталогов, содержащий около 2 миллионов файлов, но когда я выполняю команду ls, ничего не возвращается. Я ждал 3 часа. Я пробовал ls | tee directory.txt, но это, кажется, навсегда.

Я предполагаю, что сервер выполняет большую сортировку inode. Есть ли способ ускорить команду ls, чтобы просто получить список каталогов имен файлов? В настоящее время мне нет дела до размеров, дат, разрешений или тому подобного.

Ответы [ 18 ]

39 голосов
/ 02 сентября 2008
ls -U

сделает ls без сортировки.

11 голосов
/ 02 сентября 2008

Попробуйте использовать:

find . -type f -maxdepth 1

Это приведет только к списку файлов в каталоге, пропустите аргумент -type f, если вы хотите перечислить файлы и каталоги.

8 голосов
/ 02 ноября 2014

Этот вопрос кажется интересным, и я просматривал несколько ответов, которые были опубликованы. Чтобы понять эффективность опубликованных ответов, я выполнил их на 2 миллионах файлов и нашел результаты, как показано ниже.

$ time tar cvf /dev/null . &> /tmp/file-count

real    37m16.553s
user    0m11.525s
sys     0m41.291s

------------------------------------------------------

$ time echo ./* &> /tmp/file-count

real    0m50.808s
user    0m49.291s
sys     0m1.404s

------------------------------------------------------

$ time ls &> /tmp/file-count

real    0m42.167s
user    0m40.323s
sys     0m1.648s

------------------------------------------------------

$ time find . &> /tmp/file-count

real    0m2.738s
user    0m1.044s
sys     0m1.684s

------------------------------------------------------

$ time ls -U &> /tmp/file-count

real    0m2.494s
user    0m0.848s
sys     0m1.452s


------------------------------------------------------

$ time ls -f &> /tmp/file-count

real    0m2.313s
user    0m0.856s
sys     0m1.448s

------------------------------------------------------

Для подведения итогов

  1. ls -f работала немного быстрее, чем ls -U. Отключение цвета могло вызвать это улучшение.
  2. find заняла третье место со средней скоростью 2,738 секунды.
  3. Выполнение только ls заняло 42,16 секунды. Здесь в моей системе ls это псевдоним для ls --color=auto
  4. Использование функции расширения оболочки с echo ./* работало в течение 50,80 секунд.
  5. А решение на основе tar заняло около 37 миль.

Все тесты проводились отдельно, когда система находилась в режиме ожидания.

Здесь важно отметить, что списки файлов не печатаются в терминале. они были перенаправлены в файл, а число файлов было вычислено позже с помощью команды wc. Команды выполнялись слишком медленно, если выходные данные выводились на экран.

Есть идеи, почему это происходит?

6 голосов
/ 01 ноября 2014

Использование

ls -1 -f 

примерно в 10 раз быстрее, и это легко сделать (я протестировал с 1 миллионом файлов, но у моей первоначальной проблемы было 6 800 000 000 файлов)

Но в моем случае мне нужно было проверить, содержит ли какой-то конкретный каталог более 10 000 файлов. Если было более 10 000 файлов, мне уже не интересно, сколько там файлов. Я просто вышел из программы, чтобы она работала быстрее и не пытался читать остальное по одному. Если их меньше 10 000, я распечатаю точную сумму. Скорость моей программы очень похожа на ls -1 -f, если вы указываете большее значение параметра, чем количество файлов.

Вы можете использовать мою программу find_if_more.pl в текущем каталоге, набрав:

find_if_more.pl 999999999

Если вам просто интересно, если существует более n файлов, сценарий завершится быстрее, чем ls -1 -f с очень большим количеством файлов.

#!/usr/bin/perl
    use warnings;
    my ($maxcount) = @ARGV;
    my $dir = '.';
    $filecount = 0;
    if (not defined $maxcount) {
      die "Need maxcount\n";
    }
    opendir(DIR, $dir) or die $!;
    while (my $file = readdir(DIR)) {
        $filecount = $filecount + 1;
        last if $filecount> $maxcount
    }
    print $filecount;
    closedir(DIR);
    exit 0;
5 голосов
/ 18 ноября 2015

У меня есть каталог с 4 миллионами файлов, и единственный способ, которым я заставил ls сразу выплевывать файлы без большого количества взбалтывания, был

ls -1U
4 голосов
/ 27 августа 2013

Это был бы самый быстрый вариант AFAIK: ls -1 -f.

  • -1 (без столбцов)
  • -f (без сортировки)
4 голосов
/ 01 сентября 2010

Это, вероятно, не полезный ответ, но если у вас нет find, вы можете обойтись с tar

$ tar cvf /dev/null .

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

4 голосов
/ 02 сентября 2008

Вы можете перенаправить вывод и запустить процесс ls в фоновом режиме.

ls > myls.txt &

Это позволит вам продолжать заниматься своим бизнесом во время его работы. Это не заперло бы вашу оболочку.

Не уверен насчет того, какие опции есть для запуска ls и получения меньшего количества данных. Вы всегда можете запустить man ls для проверки.

2 голосов
/ 03 сентября 2008

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

В случае ls:

$strace ls

вы бы увидели, что он читает все записи каталога ( getdents (2) ), прежде чем он что-то выведет. (сортировка ... как уже было упомянуто здесь)

2 голосов
/ 02 сентября 2008

Я предполагаю, что вы используете GNU ls? попробовать

\ls

Он будет вызывать обычные ls (ls --color = auto).

...