Jeśli użyjemy, echo 1234 >> some-file
wówczas Dokumentacja mówi, że wynik jest dołączany.
Domyślam się, że jeśli jakiś plik nie istnieje, O_CREAT utworzy nowy plik. Jeśli >
został użyty, O_TRUNC obetnie istniejący plik.
W przypadku >>
: Czy plik zostanie otwarty jako O_WRONLY (lub O_RDWR) i nastąpi próba zakończenia, a operacja zapisu zostanie wykonana, symulując O_APPEND? A może plik zostanie otwarty jako O_APPEND, pozostawiając go jądrze, aby upewnić się, że nastąpi dołączenie?
Pytam o to, ponieważ proces konserwatora zastępuje niektóre znaczniki wstawione przez echo, gdy plik wyjściowy pochodzi z punktu montowania NFS, a Dokumentacja NFS mówi, że O_APPEND nie jest obsługiwany na serwerze, więc jądro klienta będzie musiało to obsłużyć. Wydaje mi się, że proces konserwatora używa O_APPEND, ale nie jestem pewien bash >>
na Linuksie, stąd zadaje pytanie tutaj.
O_APPEND
nie jest obsługiwany; problem polega na tym, że jest emulowany. W lokalnym systemie plików kilka procesów zapisujących do tego samego otwartego plikuO_APPEND
nigdy nie nadpisuje danych; na NFS,O_APPEND
jest emulowany przez dążenie do końca przed napisaniem, co pozostawia możliwość warunków wyścigowych. W NFS nie można tego obejść; każdy piszący równolegle musi napisać własny plik. Jedynym sposobem obejścia tego problemu jest skonfigurowanie procesu serwera na serwerze NFS, zalogowanie rejestratorów|nc server port
i włączenie przez serwer danych przychodzących do dziennika.Odpowiedzi:
Uruchomiłem to:
strace -o spork.out bash -c "echo 1234 >> some-file"
aby dowiedzieć się, jakie masz pytanie. Oto co znalazłem:W katalogu, w którym uruchomiłem
echo
polecenie, nie istniał żaden plik o nazwie „jakiś plik” .źródło
Jest to nie tylko wykonywane w Bash, ale jest wymagane przez standard.
Ze specyfikacji Single Unix :
Dlatego każda powłoka zgodna z POSIX musi to zrobić. W niektórych systemach uniksowych
/bin/sh
może być powłoką Bourne'a inną niż POSIX (powłoka Bourne'a została pierwotnie napisana przedO_APPEND
wynalezieniem), a zwykle dostępna będzie powłoka POSIXksh
, która będzie dostępna jaksh
w innej lokalizacji ścieżki, takiej jak Solaris/usr/xpg4/bin
.źródło
open()
.>>
sam został wprowadzony przez swojego poprzednika, powłokę Thomsona.Przeglądając źródło, używa O_APPEND. Dla bash 4.3.30 w
make_cmd.c
linii 710-713 czytamy:źródło
Zbadajmy, że
strace
w lokalnym systemie plików (innym niż NFS):Inne pociski, a mianowicie
dash
,dash
,sh
z Busybox”imksh
zachowują się tak samo.Opcja
-e open
oznacza-e trace=open
śledzenie tylkoopen()
wywołania systemowego.źródło