Если мы используем, echo 1234 >> some-file
то Документация говорит, что вывод добавлен.
Я предполагаю, что если некоторый файл не существует, то O_CREAT создаст новый файл. Если >
был использован, то O_TRUNC будет обрезать существующий файл.
В случае >>
: Будет ли файл открыт как O_WRONLY (или O_RDWR) и найден конец и операция записи выполнена, имитируя O_APPEND? Или файл будет открыт как O_APPEND, оставляя его ядру, чтобы убедиться, что добавление произойдет?
Я спрашиваю об этом, потому что процесс сохранения перезаписывает некоторые маркеры, вставленные с помощью echo, когда выходной файл находится в точке монтирования NFS, а в документации NFS говорится, что O_APPEND не поддерживается на сервере, поэтому ядру клиента придется с этим справляться. Я предполагаю, что процесс сохранения использует O_APPEND, но не уверен в bash >>
на linux, поэтому задаю вопрос здесь.
O_APPEND
она не поддерживается; проблема в том, что это эмулируется. В локальной файловой системе несколько процессов, выполняющих запись в один и тот же открытый файлO_APPEND
, никогда не будут перезаписывать данные друг друга; в NFSO_APPEND
эмулируется путем поиска до конца перед записью, что оставляет возможность состязаний. На NFS нет пути к этому; каждый параллельный писатель должен написать свой собственный файл. Единственный способ обойти это - настроить серверный процесс на NFS-сервере, сделать так, чтобы регистраторы входили в систему|nc server port
и сервер добавлял входящие данные в журнал.Ответы:
Я запустил это:
strace -o spork.out bash -c "echo 1234 >> some-file"
выяснить ваш вопрос. Вот что я нашел:В каталоге, в котором я выполнял
echo
команду, не было файла с именем some-file .источник
Это не только сделано в Bash, это требуется стандартом.
Из спецификации Unix :
Поэтому любая POSIX-совместимая оболочка должна это делать. В некоторых системах Unix это
/bin/sh
может быть не POSIX-оболочка Bourne (оболочка Bourne была изначально написана до того, какO_APPEND
была изобретена), и обычно имеется доступная оболочка POSIXksh
, которая будет доступнаsh
в другом месте пути, например в Solaris/usr/xpg4/bin
.источник
open()
.>>
Сам был представлен своим предшественником оболочкой Томсона.Глядя в источник, он использует O_APPEND. Для bash 4.3.30 в
make_cmd.c
строке 710-713 читать:источник
Давайте исследуем это, используя
strace
локальную (не NFS) файловую систему:Другие оболочки, а именно
dash
,dash
,sh
из BusyBox»иmksh
ведут себя точно так же.Опция
-e open
означает-e trace=open
отслеживать толькоopen()
системный вызов.источник