Применяет ли перенаправление вывода в файл блокировку к файлу?

Применяет ли перенаправление вывода в файл блокировку к файлу?

Если у меня есть команда

$ ./script >> file.log

который вызывается дважды, причем второй вызов происходит до завершения первого, что происходит?

Получает ли первый вызов исключительную блокировку выходного файла? Если да, то второй скрипт завершается ошибкой при попытке записи или оболочка принимает вывод (позволяя скрипту завершиться) и выдает ошибку?

Или файл журнала записывается дважды?

решение1

Системы Unix в целом избегают обязательных блокировок. Есть несколько случаев, когда ядро ​​блокирует файл от изменений пользовательскими программами, но не если он просто пишется другой программой. Ни одна система Unix не блокирует файл, потому что программа пишет в него.

Если вы хотите, чтобы параллельные экземпляры вашего скрипта не мешали друг другу, вам нужно использовать явный механизм блокировки, например:flock lockfile.

Когда вы открываете файл для добавления, что >>и происходит, каждая программа гарантированно всегда записывает в конец файла. Таким образом, вывод нескольких экземпляров никогда не перезапишет друг друга, и если они будут писать по очереди, их вывод будет в том же порядке, что и записи.

Плохая вещь, которая может случиться, это если один из экземпляров записывает несколько фрагментов вывода и ожидает, что они выйдут вместе. Между последовательными записями одного экземпляра другие экземпляры могут выполнять свои собственные записи. Например, если экземпляр 1 записывает foo, затем экземпляр 2 записывает helloи только затем экземпляр 2 записывает bar, то файл будет содержать foohellobar.

Процесс фактически записывает в файл, когда он вызывает writeсистемный вызов. Вызов writeявляется атомарным: каждый вызов writeзаписывает последовательность байтов, которая не будет прервана другими программами. Часто существует ограничение на то, сколько данных writeэффективно запишет один вызов: для больших размеров записывается только начало данных, и приложение должно вызвать writeснова. Более того, многие программы выполняютбуферизация: они накапливают данные в области памяти, а затем записывают эти данные одним куском. Некоторые программы очищают выходной буфер после полной строки или другого значимого разделения. С такими программами можно ожидать, что целые строки будут непрерывными, если они не слишком длинные (до нескольких килобайт; это зависит от ОС). Если программа не очищает в значимых местах, а только на основе размера буфера, вы можете увидеть что-то вроде 4 КБ из одного экземпляра, затем 4 КБ из другого экземпляра, затем снова 4 КБ из первого экземпляра и так далее.

решение2

Поскольку вы используете >>, что означает добавление, каждая строка вывода из каждого экземпляра будет добавлена ​​в том порядке, в котором она появилась.

Если вывод вашего скрипта выводится 1\nс 5\nзадержкой в ​​одну секунду между каждым, а экземпляр два запускается на 2,5 секунды позже, вы получите следующее:

1
2
1
3
2
4
3
5
4
5

Итак, отвечая на ваш вопрос: нет.

Связанный контент