Wstęp

Dzień dobry, dziś przedstawię kilka informacji o deskryptorach plików. Serdecznie zapraszam.

Co to takiego jest?

Deskryptor pliku (ang. FileDescriptor) jest liczbą całkowitą bez znaku (unsigned int w języku C), która identyfikuje otwarty plik ([filozofia wszystko jest plikiem] (https://mateuszlewicki.pl/2021/2021-10-08-linux6.html)).

Liczba otwartych deskryptorów jest kontrolowana przez zmienną NR_OPEN w /usr/include/linux/limits.h oraz przez flagę ulimit -n.

Deskryptory są zwykle unikalne dla procesu. Mogą natomiast być współdzielone, przez procesy potomne (fork) lub skopiowane.

Domyślne deskryptory dla procesów

Kiedy powłoka uruchamia program, otwiera ona trzy pliki (filozofia wszystko jest plikiem [soon]) z deskryptorami o numerach 0,1,2. Domyśle przypisania tych deskryptorów są następujące:

Deskryptor Reprezentacja C
0 Standardowe wejście stdin
1 Standardowe wyjście stdout
2 Standardowy błąd stderr

Te domyślne deskryptory plików są połączone z konsolą, więc kiedy program z czytuje deskryptor 0 (stdin) i drukuje do deskryptorów 1 i 2 (stdout i stderr), to program wczytuje dane z konsoli i drukuje wynik z powrotem w konsoli.

Przekierowania deskryptorów

Deskryptory plików możemy przekierowywać.

stdin

Możemy, przy pomocy znaku < (i jego wielokrotności) przekierować coś na deskryptor 0 (stdin), czyli wprowadzić coś do programu, jak np. Heredoc

Zapis będzie wyglądał następująco:

aplikacja < plikx

stdout

Możemy również przekierować deskryptor 1 (stdout) np. do pliku. Wtedy, przy pomocy znaku > i podając plik, wiadomości będą wysyłane do pliku, zamiast na ekran.

Przykład:

aplikacja > logi/aplikacja.log 

Ważnym zagadnieniem jest równica pomiędzy > a >>

Pierwszy, czyli > przekierowuje deskryptor i wiadomości bezpośrednio na początek pliku, czyli nasz plik zostanie nadpisany!

Natomiast druga opcja >> przekierowuje deskryptor i wiadomości na koniec pliku, czy każda treść, która pojawi się na stdout, zostanie dołączona, a poprzednia zawartość pozostanie nienaruszona.

stderr

Trzeci deskryptor, również możemy przekierować, lecz nie ma on już jednego znaku, którym moglibyśmy się posłużyć. W tym przypadku musimy skorzystać z kombinacji [numer]>[cel]

Dla przykładu przekieruję stdout do pliku errors.log

aplikacja > logs/aplikacja.log 2> logs/error.log

Proszę zauważyć, że przekierowałem oba deskryptory, ale tylko jeden wywołałem po numerze

kombinacja deskryptorów

Może się tak zdarzyć, że będziemy chcieli połączyć stdout i stderr i mieć wszystkie logi w jednym miejscu. Do tego zadania posłuży się nam kombinacja znaków >& która złączy dwa deskryptory w jeden.

W takim przypadku zapis będzie wyglądał tak:

aplikacja 2>&1 

Tym sposobem możemy łączyć również inne deskryptory. Dodatkowo proszę zwrócić uwagę, że każdy deskryptor jest wywołany po identyfikatorze.

Epilog

Na dziś wystarczy, mam nadzieję, że dowiedziałeś/łaś się czegoś nowego, albo odświeżyłeś/łaś sobie wiedzę. Tak czy inaczej, serdecznie Ci dziękuję, za przeczytanie tego posta. Jeśli masz potrzebę o cos zapytać, kontakt znajdziesz w zakładce “O Mnie”. A teraz życzę miłego dzionka i smacznej kawusi :) Do widzenia.