208 z 208 kodów
Operacja wymaga przywilejów, których proces nie ma, np. zmiana właściciela pliku, wysłanie sygnału do procesu innego użytkownika lub modyfikacja niezmiennego pliku (chattr +i). W przeciwieństwie do EACCES nie rozwiąże tego zmiana uprawnień pliku: potrzebny jest root lub odpowiednia capability.
Plik lub katalog nie istnieje. Pojawia się też, gdy brakuje katalogu pośredniego w ścieżce, gdy dowiązanie symboliczne wskazuje na nieistniejący cel lub gdy nie jest zainstalowany interpreter z wiersza #! skryptu.
Nie istnieje żaden proces, grupa procesów ani wątek o tym identyfikatorze; na przykład przy wywołaniu kill dla PID-u procesu, który już się zakończył.
Sygnał przerwał wywołanie systemowe, zanim się zakończyło. To nie jest prawdziwy błąd: program powinien ponowić wywołanie albo zainstalować procedurę obsługi sygnału z SA_RESTART.
Niskopoziomowy błąd wejścia/wyjścia, zwykle przy odczycie lub zapisie na urządzeniu. W przypadku dysków często oznacza uszkodzone sektory lub wadliwy kabel: sprawdź dmesg i stan SMART. Pojawia się też przy zapisie do terminala, który został już zamknięty.
Urządzenie lub adres nie istnieje: plik urządzenia jest, ale nie stoi za nim żaden sprzęt, albo otwarto do zapisu kolejkę FIFO z O_NONBLOCK bez żadnego czytelnika.
Lista argumentów i zmiennych środowiskowych przekazywana do exec jest za duża. To klasyczny błąd „Argument list too long” przy użyciu symbolu wieloznacznego, który rozwija się do tysięcy plików; użyj find -exec lub xargs.
Plik nie ma rozpoznawanego formatu wykonywalnego: to plik binarny innej architektury, jest uszkodzony albo to skrypt bez wiersza #!.
Deskryptor pliku jest nieprawidłowy, został już zamknięty lub otwarto go w trybie, który nie pozwala na operację, np. zapis do deskryptora otwartego tylko do odczytu.
Proces nie ma procesów potomnych, na które mógłby czekać za pomocą wait lub waitpid, często dlatego, że SIGCHLD jest ignorowany i procesy potomne są zbierane automatycznie.
Zasób jest chwilowo niedostępny i warto ponowić próbę. W operacjach nieblokujących oznacza, że nie ma jeszcze danych lub miejsca; w fork – że osiągnięto limit procesów lub wątków (ulimit -u lub pids.max cgroup).
Ta sama wartość:EWOULDBLOCK
Brakuje pamięci na wykonanie operacji lub przekroczono limit pamięci procesu. W fork lub mmap może to wynikać z polityki overcommit, limitu cgroup lub braku przestrzeni adresowej.
Odmowa dostępu z powodu uprawnień pliku lub katalogu w ścieżce (każdy wymaga uprawnienia do wykonywania), listy ACL, SELinux lub AppArmor albo montowania z noexec. bind zwraca go też przy użyciu portu niższego niż 1024 bez przywilejów.
Do wywołania systemowego przekazano wskaźnik na nieprawidłowy adres pamięci. Oznacza to błąd w programie.
Operacja wymaga urządzenia blokowego, takiego jak dysk, a otrzymała inny rodzaj pliku; na przykład przy montowaniu zwykłego pliku bez -o loop.
Urządzenie lub zasób jest zajęty. Typowe przy odmontowywaniu systemu plików, w którym są otwarte pliki lub w którym znajduje się bieżący katalog terminala; lsof lub fuser pokażą, które procesy go używają.
Plik, katalog lub inny obiekt o tej nazwie już istnieje, np. przy tworzeniu z O_EXCL, użyciu mkdir bez -p lub tworzeniu dowiązania, którego cel już istnieje.
Nie można utworzyć dowiązania twardego ani zmienić nazwy pliku między różnymi systemami plików. mv radzi sobie z tym, kopiując i usuwając; programy używające rename() muszą zrobić to samo.
Urządzenie nie istnieje lub nie obsługuje operacji; na przykład przy montowaniu typu systemu plików, którego moduł jądra nie jest załadowany.
Element ścieżki, który powinien być katalogiem, jest plikiem, albo zażądano katalogu (O_DIRECTORY), a nim nie jest.
Próbowano wykonać na katalogu operację przeznaczoną dla plików, np. otworzyć go do zapisu.
Argument jest nieprawidłowy dla danego wywołania: wartość spoza zakresu, niezgodna kombinacja opcji lub operacja, której obiekt nie obsługuje. To błąd ogólny: strona man wywołania wymienia konkretne przypadki.
Wyczerpała się ogólnosystemowa tabela otwartych plików. Limit ustawia się za pomocą fs.file-max w sysctl.
Proces osiągnął limit otwartych deskryptorów („Too many open files”). Podnieś limit za pomocą ulimit -n lub LimitNOFILE w systemd i sprawdź, czy program nie zostawia niezamkniętych plików lub gniazd.
Zażądano operacji terminalowej (ioctl) na czymś, co nie jest terminalem, np. gdy wyjście programu interaktywnego jest przekierowane do pliku lub potoku.
Plik wykonywalny jest w użyciu: nie można zapisywać do pliku binarnego podczas jego działania ani uruchomić takiego, który jest nadal otwarty do zapisu. Aby go zaktualizować, lepiej zapisać nowy plik i zmienić jego nazwę.
Plik przekracza maksymalny rozmiar obsługiwany przez system plików (4 GB w FAT32) lub limit RLIMIT_FSIZE procesu.
Brak miejsca na urządzeniu. Jeśli df pokazuje wolne miejsce, sprawdź i-węzły za pomocą df -i. inotify również go zwraca po wyczerpaniu fs.inotify.max_user_watches.
Nie można wykonać lseek na potoku, kolejce FIFO ani gnieździe, ponieważ nie mają one pozycji.
System plików jest zamontowany tylko do odczytu. Jeśli przeszedł w tryb tylko do odczytu, choć nikt o to nie prosił, zrobiło to jądro po wykryciu błędów: sprawdź dmesg i uruchom fsck.
Przekroczono maksymalną liczbę dowiązań twardych do pliku lub, w niektórych systemach plików, podkatalogów w katalogu.
Zapisano do potoku lub gniazda, którego drugi koniec został już zamknięty („Broken pipe”). Oprócz błędu proces otrzymuje SIGPIPE; to normalne, gdy czytelnik kończy wcześniej, jak w cmd | head.
Argument funkcji matematycznej jest poza jej dziedziną, np. pierwiastek kwadratowy z liczby ujemnej.
Wynik funkcji jest zbyt duży lub zbyt mały, by go przedstawić, albo bufor jest za mały na wynik, jak w getcwd z krótkim buforem.
Uniknięto zakleszczenia: żądana blokada, np. blokada pliku przez fcntl lub mutex z wykrywaniem błędów, czekałaby w nieskończoność.
Ta sama wartość:EDEADLOCK
Ścieżka lub jeden z jej elementów przekracza maksymalną długość: w Linuksie zwykle 255 bajtów na nazwę i 4096 na ścieżkę.
Brak dostępnych blokad. W NFS zwykle oznacza, że usługa blokad (lockd lub rpc.statd) nie działa.
Wywołanie systemowe nie istnieje w tym jądrze lub nie jest zaimplementowane. Typowe dla plików binarnych skompilowanych dla nowszego jądra albo dla profili seccomp kontenerów, które nie znają nowych wywołań.
Katalog nie jest pusty, np. przy użyciu rmdir lub zmianie nazwy na istniejący katalog. Aby usunąć go wraz z zawartością, użyj rm -r.
Przy rozwiązywaniu ścieżki napotkano zbyt wiele połączonych dowiązań symbolicznych, zwykle z powodu pętli, albo użyto O_NOFOLLOW na dowiązaniu symbolicznym.
W kolejce komunikatów System V nie ma komunikatu żądanego typu.
Identyfikator IPC System V (kolejka, semafor lub pamięć współdzielona) został usunięty, gdy proces go używał.
Numer kanału poza zakresem. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Poziom 2 niezsynchronizowany. To przestarzały kod z System V bez praktycznego zastosowania w Linuksie.
Poziom 3 zatrzymany. To przestarzały kod z System V bez praktycznego zastosowania w Linuksie.
Poziom 3 zresetowany. To przestarzały kod z System V bez praktycznego zastosowania w Linuksie.
Numer łącza poza zakresem. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Sterownik protokołu nie jest podłączony. Używa go niewiele podsystemów, np. niektóre sterowniki Bluetooth.
Brak dostępnej struktury CSI. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Poziom 2 zatrzymany. To przestarzały kod z System V bez praktycznego zastosowania w Linuksie.
Nieprawidłowa wymiana. To przestarzały kod, który niektóre sterowniki i systemy plików wykorzystują ponownie z własnym znaczeniem.
Nieprawidłowy deskryptor żądania. To przestarzały kod, który niektóre sterowniki wykorzystują ponownie z własnym znaczeniem.
Wymiana pełna. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Brak „anode”. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Nieprawidłowy kod żądania. To kod przestarzały; niektóre sterowniki używają go dla poleceń, których nie obsługują.
Nieprawidłowy slot. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Nieprawidłowy format pliku czcionki. To przestarzały kod bez praktycznego zastosowania w Linuksie.
Urządzenie nie jest STREAM. Należy do interfejsu STREAMS z System V, którego Linux nie implementuje.
Brak dostępnych danych. W Linuksie zwraca go getxattr, gdy atrybut rozszerzony nie istnieje; w macOS ten przypadek to ENOATTR.
Upłynął czas timera. Pochodzi ze STREAMS; w Linuksie używają go niektóre sterowniki oraz io_uring dla operacji z limitem czasu.
Wyczerpały się zasoby STREAMS – interfejsu, którego Linux nie implementuje.
Komputer nie jest w sieci. To przestarzały, rzadko używany kod.
Pakiet nie jest zainstalowany. To kod przestarzały; niektóre podsystemy używają go, gdy brakuje modułu, np. kryptograficznego.
Obiekt jest zdalny. W NFS oznacza ścieżkę eksportowaną z innego serwera.
Łącze zostało zerwane. To kod przestarzały; niektóre sterowniki używają go po utracie połączenia z urządzeniem.
Błąd „advertise”. To przestarzały kod z RFS, nieużywany w Linuksie.
Błąd „srmount”. To przestarzały kod z RFS, nieużywany w Linuksie.
Błąd komunikacji podczas wysyłania. To kod przestarzały; używają go niektóre sterowniki sieciowe i USB.
Błąd protokołu: druga strona lub urządzenie odpowiedziało czymś nieoczekiwanym. Pojawia się przy urządzeniach USB i w połączeniach zerwanych w trakcie wymiany.
Próbowano wykonać wielokrotny przeskok (multihop). To przestarzały kod z RFS.
Błąd specyficzny dla RFS. Nieużywany w Linuksie.
Komunikat jest źle sformułowany lub uszkodzony. ext4, XFS i Btrfs zwracają go, z aliasem EFSBADCRC, gdy nie zgadza się suma kontrolna metadanych.
Ta sama wartość:EFSBADCRC
Wartość nie mieści się w docelowym typie danych; na przykład gdy 32-bitowy program skompilowany bez obsługi dużych plików otwiera plik większy niż 2 GB.
Nazwa nie jest unikatowa w sieci. To przestarzały kod.
Deskryptor pliku jest w nieprawidłowym stanie. Używają go ALSA i niektóre sterowniki, gdy urządzenie nie jest gotowe.
Zmienił się adres zdalny. To przestarzały kod.
Brak dostępu do wymaganej biblioteki współdzielonej. To przestarzały kod z plików binarnych a.out.
Biblioteka współdzielona jest uszkodzona. To przestarzały kod z plików binarnych a.out.
Sekcja .lib pliku binarnego a.out jest uszkodzona. To przestarzały kod.
Próbowano dołączyć zbyt wiele bibliotek współdzielonych. To przestarzały kod z a.out.
Biblioteki współdzielonej nie można uruchomić bezpośrednio. To przestarzały kod z a.out.
Sekwencja bajtów jest nieprawidłowa dla kodowania znaków, np. tekst, który nie jest poprawnym UTF-8, przy konwersji za pomocą iconv lub funkcji wielobajtowych.
Przerwane wywołanie należy uruchomić ponownie. Służy do wewnętrznego użytku jądra i nie powinno docierać do programów.
Błąd potoku STREAMS. ALSA zwraca go, gdy urządzenie audio jest wstrzymane.
Zbyt wielu użytkowników. Zwraca go system przydziałów dyskowych, gdy zapełni się jego tabela; występuje rzadko.
Użyto operacji na gnieździe na deskryptorze, który nie jest gniazdem.
Brak adresu docelowego: wysłano dane przez gniazdo bezpołączeniowe bez wskazania, dokąd.
Komunikat jest za duży dla gniazda, np. datagram UDP większy niż maksimum lub niż MTU, gdy fragmentacja jest niedozwolona.
Protokół nie odpowiada typowi gniazda.
Żądana opcja gniazda lub protokół nie jest dostępny, np. opcja setsockopt, której jądro nie zna.
Protokół nie jest obsługiwany, np. dlatego, że jego moduł jądra nie jest załadowany.
Typ gniazda nie jest obsługiwany w tej rodzinie adresów.
Operacja nie jest obsługiwana przez gniazdo lub obiekt. W Linuksie ma tę samą wartość co ENOTSUP, a wiele systemów plików zwraca go dla funkcji, których nie implementuje, np. fallocate lub atrybutów rozszerzonych.
Operacja nie jest obsługiwana. W Linuksie ma tę samą wartość co EOPNOTSUPP (95); w macOS to różne kody.
Rodzina protokołów nie jest obsługiwana.
Rodzina adresów nie jest obsługiwana; typowe przy użyciu IPv6 w systemie lub kontenerze, w którym jest wyłączone.
Adres i port są już w użyciu: inny proces nasłuchuje na tym porcie lub poprzednie połączenie jest wciąż w stanie TIME_WAIT. Znajdź proces za pomocą ss -ltnp lub lsof -i :PORT albo użyj SO_REUSEADDR.
Nie można przypisać żądanego adresu: IP nie należy do żadnego interfejsu komputera albo wyczerpały się porty efemeryczne dla połączeń wychodzących.
Interfejs sieciowy nie działa.
Sieć docelowa jest nieosiągalna, bo nie ma do niej żadnej trasy. Sprawdź tablicę routingu i bramę; zdarza się też przy łączeniu przez IPv6 bez łączności IPv6.
Sieć zresetowała połączenie, np. gdy zawiedzie keepalive.
Połączenie zostało przerwane po stronie lokalnej, np. dlatego, że klient je zamknął, zanim serwer przyjął je przez accept.
Druga strona gwałtownie zerwała połączenie pakietem RST („Connection reset by peer”): zdalny proces się zamknął, zapora lub load balancer zerwał nieaktywne połączenie albo wysłano dane, których druga strona się nie spodziewała.
W jądrze brakuje miejsca w buforach na operację sieciową; zwykle pojawia się przy dużym ruchu lub pełnych kolejkach gniazd.
Gniazdo jest już połączone.
Gniazdo nie jest połączone: próbowano wysyłać lub odbierać przed połączeniem albo połączenie zostało już zamknięte. W punkcie montowania FUSE pojawia się jako „Transport endpoint is not connected”, gdy jego proces zakończył działanie; naprawia się to, odmontowując go za pomocą fusermount -u.
Nie można wysyłać po zamknięciu tego kierunku gniazda za pomocą shutdown.
Zbyt wiele odwołań; w Linuksie przy przekazywaniu zbyt wielu zagnieżdżonych deskryptorów przez gniazdo uniksowe.
Upłynął limit czasu połączenia, bo cel nie odpowiedział. Zwykle przyczyną jest zapora, która po cichu odrzuca pakiety, wyłączony host lub trasa, która nie prowadzi do celu.
Cel odrzucił połączenie: komputer odpowiada, ale nikt nie nasłuchuje na tym porcie lub zapora odpowiada odmową. Sprawdź, czy usługa działa i nasłuchuje na właściwym interfejsie, a nie tylko na 127.0.0.1.
Host docelowy nie działa.
Brak trasy do hosta: nie odpowiada na ARP w sieci lokalnej albo router lub zapora zgłasza, że jest nieosiągalny.
Na gnieździe trwa już operacja, np. nieblokujący connect, który jeszcze się nie zakończył.
Operacja jest w toku: nieblokujący connect się rozpoczął i zakończy się później. To nie błąd; trzeba poczekać za pomocą poll lub select.
Uchwyt pliku jest nieaktualny: w NFS plik lub katalog został usunięty lub zastąpiony na serwerze. Rozwiązaniem jest ponowne otwarcie ścieżki lub ponowne zamontowanie.
Struktura wymaga wyczyszczenia: system plików wykrył uszkodzenie (w ext4 i XFS z aliasem EFSCORRUPTED). Odmontuj go i uruchom fsck lub xfs_repair.
Ta sama wartość:EFSCORRUPTED
To nie jest plik nazwany XENIX. To przestarzały, nieużywany kod.
Brak dostępnych semaforów XENIX. To przestarzały, nieużywany kod.
To plik nazwany XENIX. To przestarzały, nieużywany kod.
Zdalny błąd wejścia/wyjścia, np. urządzenia I2C lub zdalnego dysku, który nie odpowiedział.
Przekroczono przydział dyskowy użytkownika lub grupy.
W urządzeniu nie ma nośnika, np. napęd bez płyty lub pusty czytnik kart.
Nieprawidłowy typ nośnika.
Operacja została anulowana, np. asynchroniczne wejście/wyjście lub oczekiwanie io_uring.
Wymaganego klucza nie ma w keyringu jądra. Pojawia się przy szyfrowanych systemach plików, takich jak fscrypt lub eCryptfs, gdy klucz nie został załadowany.
Klucz wygasł. PAM i Kerberos używają go też, gdy wygasło hasło lub bilet.
Klucz został unieważniony.
Usługa odrzuciła klucz.
Właściciel odpornego mutexu zakończył działanie, nie zwalniając go. Nowy właściciel musi przywrócić spójność chronionego stanu i wywołać pthread_mutex_consistent.
Stanu chronionego przez odporny mutex nie da się odzyskać, ponieważ poprzedni właściciel zakończył działanie i nikt nie oznaczył stanu jako spójnego.
Operacja nie jest możliwa, bo radio Wi-Fi lub Bluetooth jest zablokowane przez RF-kill. Sprawdź rfkill list, fizyczny przełącznik lub klawisz trybu samolotowego.
Strona pamięci ma błąd sprzętowy i jądro oznaczyło ją jako zatrutą.
Typ pliku jest nieodpowiedni dla operacji. W macOS i BSD istnieje od dawna; do Linuksa dodano go niedawno.
Zbyt wiele procesów. BSD definiuje go dla limitu procesów, choć w praktyce fork zwraca EAGAIN.
Nieprawidłowa struktura RPC (Sun RPC, używane przez NFS).
Niezgodna wersja RPC (Sun RPC, używane przez NFS).
Program RPC jest niedostępny na serwerze.
Niezgodna wersja programu RPC.
Procedura nie istnieje w programie RPC.
Błąd uwierzytelniania, np. przy montowaniu zasobu NFS.
Operacja wymaga uwierzytelniacza.
Urządzenie jest wyłączone.
Błąd urządzenia, np. drukarka bez papieru.
Plik wykonywalny jest nieprawidłowy.
Plik wykonywalny jest przeznaczony dla innego typu procesora, np. plik binarny tylko dla x86_64 na Macu z Apple Silicon bez Rosetta 2 albo plik ARM na Macu z procesorem Intel.
Niezgodna wersja biblioteki współdzielonej.
Plik Mach-O jest źle sformułowany lub uszkodzony.
Atrybut rozszerzony nie istnieje; odpowiada linuksowemu ENODATA. Pojawia się przy xattr, np. przy usuwaniu com.apple.quarantine z pliku, który go nie ma.
W MAC Framework nie ma zarejestrowanej polityki o tej nazwie.
Kolejka wyjściowa interfejsu sieciowego jest pełna.
Niewystarczające uprawnienia (capabilities): zwracają go wywołania ograniczone przez piaskownicę.
Terminal sterujący procesem został zamknięty lub sesja SSH została przerwana. Wiele demonów, takich jak nginx, sshd czy rsyslog, traktuje go jako polecenie ponownego wczytania konfiguracji; nohup, tmux i screen zapobiegają temu, by zamykał procesy po wyjściu.
Przerwanie z klawiatury za pomocą Ctrl+C. Program może go przechwycić, by zakończyć działanie w uporządkowany sposób. Kod wyjścia 130.
Wyjście z klawiatury za pomocą Ctrl+\. Kończy proces ze zrzutem pamięci; JVM natomiast używa go do wypisania stanu wątków.
Procesor napotkał niedozwoloną instrukcję: plik binarny skompilowany dla nowszego procesora (np. z AVX2 lub AVX-512 na procesorze, który ich nie ma), uszkodzony kod lub skok do danych.
Pułapka debugowania: debugery używają go do punktów przerwania. Jeśli pojawia się bez debugera, zwykle jest to błąd wykryty przez sam program, np. przez kontrole Swifta w macOS.
Proces wywołał abort(): nieudana asercja, nieprzechwycony wyjątek C++ lub uszkodzenie sterty wykryte przez bibliotekę C („double free or corruption”). Kod wyjścia 134.
Ta sama wartość:SIGIOT
Błąd magistrali: dostęp do niewyrównanej pamięci w niektórych architekturach lub do części pliku zmapowanego przez mmap, która już nie istnieje, bo plik został obcięty. Zdarza się też, gdy zapełni się /dev/shm.
Wyjątek arytmetyczny. Wbrew nazwie najczęstszą przyczyną jest dzielenie całkowite przez zero.
Natychmiast kończy proces: nie można go przechwycić, zablokować ani zignorować. Wysyłają go kill -9, OOM killer jądra po wyczerpaniu pamięci oraz Docker lub Kubernetes, gdy kontener przekroczy limit pamięci (OOMKilled) lub nie zakończy się na czas po SIGTERM. Kod wyjścia 137.
Wolny sygnał, któremu każda aplikacja nadaje własne zastosowanie; na przykład dd wypisuje postęp, a nginx ponownie otwiera logi.
Naruszenie ochrony pamięci („Segmentation fault”): dostęp do nieprawidłowej pamięci, np. dereferencja wskaźnika null, wyjście poza tablicę lub przepełnienie stosu przez nieskończoną rekurencję. Kod wyjścia 139.
Drugi wolny sygnał, któremu każda aplikacja nadaje własne zastosowanie.
Zapis do potoku lub gniazda bez czytelnika. To normalne w cmd | head, gdzie czytelnik kończy wcześniej; serwery zwykle go ignorują i obsługują błąd EPIPE. Kod wyjścia 141.
Upłynął czas timera ustawionego przez alarm lub setitimer.
Prośba o uporządkowane zakończenie. To domyślny sygnał kill, systemctl stop, docker stop oraz Kubernetesa przy usuwaniu poda; proces powinien zamknąć połączenia i zakończyć działanie. Kod wyjścia 143.
Błąd stosu koprocesora. Nieużywany we współczesnym Linuksie.
Proces potomny zakończył się, zatrzymał lub wznowił działanie. Rodzic musi go odebrać za pomocą wait; w przeciwnym razie potomek pozostaje zombie.
Ta sama wartość:SIGCLD
Wznawia zatrzymany proces, tak jak robią to fg i bg w powłoce.
Zatrzymuje proces; nie można go przechwycić ani zignorować. Proces wznawia się sygnałem SIGCONT.
Zatrzymanie z terminala za pomocą Ctrl+Z. W przeciwieństwie do SIGSTOP program może go przechwycić.
Proces działający w tle próbował czytać z terminala.
Proces działający w tle próbował pisać do terminala przy włączonym stty tostop lub zmienić jego konfigurację.
Do gniazda dotarły dane pilne (poza pasmem). Go używa go wewnętrznie do przerywania gorutyn.
Przekroczono limit czasu procesora dla procesu (ulimit -t).
Przekroczono maksymalny rozmiar pliku dozwolony dla procesu (ulimit -f).
Upłynął czas timera wirtualnego, który liczy tylko czas procesora zużyty przez proces.
Upłynął czas timera profilowania, używanego przez profilery.
Zmienił się rozmiar okna terminala; programy pełnoekranowe używają go, by przerysować interfejs.
Na deskryptorze skonfigurowanym z O_ASYNC dostępne jest wejście/wyjście. W Linuksie SIGPOLL to ten sam sygnał.
Ta sama wartość:SIGPOLL
Awaria zasilania, którą oprogramowanie UPS zgłasza systemowi init.
Nieprawidłowe wywołanie systemowe. Obecnie zwykłą przyczyną jest filtr seccomp, który je blokuje, np. w kontenerach.
Pułapka emulacji (EMT). Istnieje w macOS i BSD, ale nie w Linuksie na x86 ani ARM.
Żądanie informacji za pomocą Ctrl+T w terminalu macOS i BSD; wiele poleceń odpowiada, pokazując postęp.
Polecenie zakończyło się pomyślnie. To jedyny kod oznaczający sukces: każda inna wartość wskazuje błąd.
Błąd ogólny; każdy program sam decyduje, co oznacza. Szczegóły zwykle są w tym, co polecenie wypisało na stderr. grep i diff używają go w innym znaczeniu: „nie znaleziono dopasowań” lub „pliki się różnią”.
Nieprawidłowe użycie wbudowanego polecenia powłoki lub błąd składni w skrypcie. Wiele programów używa go też dla nieprawidłowych opcji, a grep dla rzeczywistych błędów.
Polecenie zostało użyte nieprawidłowo: brakuje argumentów, jest ich za dużo lub któraś opcja jest błędna.
Dane wejściowe mają nieprawidłowy format.
Plik wejściowy nie istnieje lub nie można go odczytać.
Wskazany użytkownik nie istnieje; używają go głównie programy pocztowe.
Nazwa hosta nie istnieje.
Wymagana usługa jest niedostępna lub zawiodło coś, co nie pasuje do innej kategorii.
Wewnętrzny błąd programu.
Błąd systemu operacyjnego, np. niemożność wykonania fork lub utworzenia potoku.
Brakuje pliku systemowego, takiego jak /etc/passwd, lub zawiera on błąd.
Nie można utworzyć pliku wyjściowego.
Błąd wejścia/wyjścia przy odczycie lub zapisie pliku.
Błąd tymczasowy: warto spróbować ponownie później. Serwery pocztowe używają go, by zostawić wiadomość w kolejce.
System zdalny odpowiedział czymś, co nie jest zgodne z protokołem.
Niewystarczające uprawnienia do wykonania operacji.
W konfiguracji jest błąd.
Polecenie timeout zakończyło je, bo przekroczyło wskazany czas.
Zawiodło samo docker run, zanim uruchomiło kontener, np. z powodu błędnej opcji lub błędu demona. GNU timeout również go zwraca, gdy to on sam zawodzi.
Plik istnieje, ale nie można go uruchomić: brakuje uprawnienia do wykonywania, jest katalogiem lub plikiem binarnym innej architektury. W Dockerze polecenie kontenera nie jest wykonywalne.
Nie znaleziono polecenia: nie jest zainstalowane, nie ma go w PATH lub jego nazwa jest błędnie zapisana. W skryptach pojawia się też, gdy brakuje interpretera z wiersza #!; w Dockerze – gdy polecenie kontenera nie istnieje w obrazie.
Kody większe niż 128 oznaczają, że proces zakończył sygnał, ale 128 nie odpowiada żadnemu. Git używa go dla wszystkich swoich błędów krytycznych („fatal: …”), np. nieistniejącego repozytorium lub błędu uwierzytelniania przy klonowaniu.
Kod wyjścia był poza zakresem: exit -1 dociera jako 255, bo zachowywanych jest tylko 8 bitów. ssh również go zwraca, gdy zawiedzie połączenie lub uwierzytelnianie, aby odróżnić go od kodu zdalnego polecenia.
Wartości dla Linuksa dotyczą x86, x86-64 i ARM; Alpha, MIPS, SPARC i PA-RISC numerują niektóre errno i sygnały inaczej. Komunikaty po angielsku to te, które wyświetlają strerror i strsignal w glibc, a także w macOS, gdy są inne. Kody wyjścia większe niż 128 interpretuje się jako 128 plus numer sygnału, zgodnie z konwencją bash, Dockera i Kubernetesa.
Jak to działa
Gdy wywołanie systemowe w Linuksie się nie powiedzie, zwraca -1 i zapisuje w zmiennej errno liczbę wskazującą przyczynę: 2 to ENOENT, plik nie istnieje; 13 to EACCES, odmowa dostępu. strerror zamienia tę liczbę na tekst widoczny na ekranie, np. „No such file or directory”. Python pokazuje go jako [Errno 13], Node.js jako code: 'ECONNREFUSED', a Go, Rust czy Java – tym samym tekstem. Numery od 1 do 34 pochodzą z oryginalnego Uniksa i są takie same we wszystkich systemach; kolejne każdy system ponumerował po swojemu, więc ECONNREFUSED to 111 w Linuksie i 61 w macOS. Nazwa jest przenośna; numer nie.
Sygnały to powiadomienia, które jądro lub inny proces wysyła do procesu: SIGINT po naciśnięciu Ctrl+C, SIGTERM, by poprosić go o zakończenie, SIGKILL, by zakończyć go bez pytania, SIGSEGV, gdy odwołuje się do nieprawidłowej pamięci. Każdy ma domyślną akcję, a prawie wszystkie można przechwycić, by zrobić coś innego. Gdy sygnał zabije proces, powłoka zgłasza jako kod wyjścia 128 plus numer sygnału: 137 to SIGKILL (9), 139 to SIGSEGV (11), a 143 to SIGTERM (15). Docker i Kubernetes stosują tę samą konwencję.
Kod wyjścia to liczba, którą program zostawia po zakończeniu: 0 oznacza sukces, a każda inna wartość błąd. Zachowywanych jest tylko 8 bitów, więc mieści się w zakresie od 0 do 255. Konwencji jest niewiele: 126 i 127 używa powłoka, gdy nie może uruchomić lub nie znajduje polecenia, od 64 do 78 definiuje sysexits.h z BSD, a resztę ustala każdy program, np. grep, który zwraca 1, gdy nic nie znajdzie.
Przykłady
Last State: Terminated · Reason: OOMKilled · Exit Code: 137137 = 128 + 9 · SIGKILLKontener przekroczył limit pamięci i jądro zabiło go sygnałem SIGKILL. Trzeba podnieść limit w resources.limits.memory lub ustalić, dlaczego proces zużywa tak dużo; ponowne uruchomienie tego nie naprawi.Error: connect ECONNREFUSED 127.0.0.1:5432ECONNREFUSED · Linux 111 · macOS 61 · Connection refusedNode.js nie mógł połączyć się z PostgreSQL, bo nikt nie nasłuchuje na porcie 5432. Jeśli aplikacja działa w kontenerze, 127.0.0.1 to sam kontener, a nie komputer: trzeba użyć nazwy usługi bazy danych.OSError: [Errno 48] Address already in useEADDRINUSE · Linux 98 · macOS 4848 zdradza, że program działa w macOS: w Linuksie ten sam błąd ma numer 98. W obu przypadkach port jest już używany przez inny proces; lsof -i :PORT pokaże który.Przypadki użycia
- Zrozumieć błąd aplikacji w Pythonie, Node.js, Go lub C, która pokazuje tylko numer lub nazwę errno.
- Ustalić na podstawie kodu wyjścia, dlaczego zamknął się kontener Dockera lub restartuje się pod Kubernetesa.
- Zamienić numer errno z macOS na właściwą nazwę, ponieważ od 35 numery nie pokrywają się z linuksowymi.
- Zinterpretować kod wyjścia skryptu, zadania cron lub joba CI, który zakończył się niepowodzeniem.
- Wybrać, jaki sygnał wysłać za pomocą kill, i wiedzieć, co zrobi proces, jeśli go nie przechwyci.
- Napisać przenośną obsługę błędów, która porównuje po nazwie, a nie po numerze.
Najczęstsze pytania
Co oznacza exit code 137?
Że proces został zakończony sygnałem 9, SIGKILL (128 + 9). Najczęstszą przyczyną jest pamięć: kontener przekroczył swój limit, co Kubernetes zgłasza jako OOMKilled, albo OOM killer jądra wybrał ten proces, co zostaje w dmesg jako „Out of memory: Killed process”. Zdarza się też przy docker kill lub gdy proces nie zakończy się w wyznaczonym czasie po SIGTERM: 10 sekund w docker stop i 30 w Kubernetesie.
Jaka jest różnica między SIGTERM a SIGKILL?
SIGTERM prosi proces o zakończenie, a proces może go przechwycić, by zamknąć połączenia, zapisać dane i wyjść. Przy SIGKILL to jądro natychmiast kończy proces, a ten nie może nic zrobić. Właściwie jest wysłać SIGTERM, odczekać kilka sekund i sięgnąć po SIGKILL tylko wtedy, gdy proces nadal działa – tak robią systemd, docker stop i Kubernetes.
Dlaczego to samo errno ma w macOS inny numer?
Ponieważ POSIX definiuje nazwy, ale nie numery. Od 1 do 34 wszystkie systemy odziedziczyły numery z oryginalnego Uniksa; potem BSD, z którego wywodzi się macOS, i System V, za którym poszedł Linux, numerowały je osobno. Dlatego zawsze warto porównywać po nazwie – za pomocą errno.ECONNREFUSED w Pythonie, err.code w Node.js lub stałej w C – a nie po numerze.
Jaka jest różnica między EACCES a EPERM?
EACCES („Permission denied”) oznacza, że nie pozwalają na to uprawnienia pliku lub któregoś katalogu w ścieżce albo blokuje to ACL lub SELinux: rozwiązuje się to za pomocą chmod, chown lub odpowiedniej polityki. EPERM („Operation not permitted”) oznacza, że sama operacja wymaga przywilejów niezależnie od uprawnień, np. zmiana właściciela pliku lub zabicie procesu innego użytkownika: potrzebny jest root, capability albo usunięcie atrybutu, takiego jak niezmienność.
Jak sprawdzić kod wyjścia polecenia lub kontenera?
W bash i zsh echo $? pokazuje kod ostatniego polecenia; w PowerShell – $LASTEXITCODE. W Dockerze docker ps -a pokazuje go w kolumnie STATUS, np. „Exited (137)”. W Kubernetesie kubectl describe pod pokazuje go w „Last State: Terminated” wraz z przyczyną, np. OOMKilled lub Error.