Ваши перенаправления находятся в состоянии гонки. Это:
>(wc -l | awk '{print $1}' > n.txt)
выполняется параллельно с:
awk 'BEGIN{getline n < "n.txt"}...'
позже в конвейере. Иногда n.txt
все еще пуст, когда запускается программа awk
.
Это (косвенно) задокументировано в Справочном руководстве Bash. В конвейере :
Выход каждой команды в конвейере соединяется через конвейер с входом следующей команды. То есть каждая команда считывает вывод предыдущей команды. Это соединение выполняется перед любыми перенаправлениями, указанными командой .
, а затем:
Каждая команда в конвейере выполняется в своей собственной подоболочке
(курсив добавлен). Все процессы в конвейере запускаются, их вход и выход соединены вместе, без ожидания завершения или даже начала каких-либо действий из предыдущих программ. До этого подстановка процесса на > (...)
:
выполняется одновременно с расширением параметров и переменных, подстановкой команд и арифметическим расширением.
Это означает, что подпроцесс, выполняющий wc -l | Команда awk ...
запускается раньше, и перенаправление очищает n.txt
непосредственно перед этим, но процесс awk
, вызывающий ошибку, запускается вскоре после этого. Обе эти команды выполняются параллельно - здесь у вас будет одновременно выполняться несколько процессов.
Ошибка возникает, когда awk
запускает свой блок BEGIN
до того, как выходные данные команды wc
будут записаны в n.txt
. В этом случае переменная n
пуста и поэтому равна нулю при использовании в качестве числа. Если BEGIN
запускается после заполнения файла, все работает.
Когда это произойдет, зависит от планировщика операционной системы и от того, какой процесс получает слот первым, что, по сути, является случайным с точки зрения пользователя. Если последний awk
запускается раньше или конвейер wc
планируется немного позже, файл все равно будет пустым, когда awk
начнет выполнять свою работу и все это сломается. По всей вероятности, процессы будут выполняться на разных ядрах одновременно, и это зависит от того, какой из них первым дойдет до точки разногласий. Эффект, который вы получите, вероятно, заключается в том, что команда работает чаще, чем нет, но иногда дает сбой с ошибкой, которую вы публикуете.
В общем, конвейеры безопасны только постольку, поскольку они просто конвейеры - стандартный вывод в стандартный ввод - это нормально, но поскольку процессы выполняются параллельно , полагаться на последовательность любого другого обмена данными ненадежно. каналы , такие как файлы, или любой части любого одного процесса, выполняющегося до или после любой части другого, если они не заблокированы вместе путем чтения стандартного ввода.
Обходной путь здесь, вероятно, состоит в том, чтобы записывать все файлы до того, как они понадобятся: в конце строки гарантируется, что весь конвейер и все его перенаправления завершены до запуска следующей команды. Эта команда никогда не будет надежной, но если она вам действительно нужна для работы в такой структуре, вы можете вставить задержку ( sleep
) или цикл до тех пор, пока n.txt
не станет нестандартным. -empty перед запуском последней команды awk
, чтобы увеличить шансы, что все будет работать так, как вы хотите.
Если у вас есть возможность разделить диск самостоятельно, вы можете решить количество inodes на раздел.
Вот как:
Вы можете сделать немного математики и использовать опцию -I
, с вашим MKFS. *
MKFS. * Команда для определения количества созданных inodes.
-i bytes-per-inode
Specify the bytes/inode ratio. mke2fs creates an inode for every bytes-per-inode bytes of space on the
disk. The larger the bytes-per-inode ratio, the fewer inodes will be created. This value generally
shouldn't be smaller than the blocksize of the filesystem, since in that case more inodes would be made than
can ever be used. Be warned that it is not possible to expand the number of inodes on a filesystem after it
is created, so be careful deciding the correct value for this parameter.
Для удобства расчета позволяет сказать размер вашего диска составляет 10 000 000 байтов, теперь, если вы используете:
MKFS.SEX4 -I 1000 / DEV / YourDrive
Это отформатирует диск и создает 1 inode PER 1000 байтов, т. Е. На вашем 10 000 000 байтов ездит он создаст 10000 inodes. По умолчанию соотношение BYTES-PER-INODE INODE
составляет 16384, как определено в /etc/mke2fs.conf
, если у вас нет возможности разделить диск самостоятельно, то я Извините, вы не можете изменить количество inodes.