Jestem raczej mylony z celem tych trzech plików. Jeśli dobrze rozumiem, stdin
to plik, w którym program zapisuje swoje żądania uruchomienia zadania w tym procesie, stdout
to plik, w którym jądro zapisuje dane wyjściowe, a proces żądający dostępu do informacji z niego stderr
jest plikiem w których wpisane są wszystkie wyjątki. Po otwarciu tych plików, aby sprawdzić, czy rzeczywiście się zdarzają, nic nie sugeruje!
Chciałbym wiedzieć, jaki jest dokładnie cel tych plików, absolutnie głupia odpowiedź z bardzo małym żargonem technologicznym!
Odpowiedzi:
Standardowe dane wejściowe - jest to uchwyt pliku odczytywany przez proces w celu uzyskania od ciebie informacji.
Standardowe wyjście - twój proces zapisuje normalne informacje do tego uchwytu pliku.
Błąd standardowy - proces zapisuje informacje o błędzie do tego uchwytu pliku.
To jest tak głupie, jak tylko mogę :-)
Oczywiście dzieje się tak głównie na podstawie konwencji. Nic nie stoi na przeszkodzie, aby zapisać informacje o błędzie na standardowym wyjściu, jeśli chcesz. Możesz nawet całkowicie zamknąć trzy uchwyty plików i otworzyć własne pliki dla operacji we / wy.
Kiedy proces się rozpocznie, powinien już mieć otwarte uchwyty i może po prostu czytać i / lub pisać do nich.
Domyślnie są one prawdopodobnie podłączone do twojego urządzenia końcowego (np.
/dev/tty
), Ale powłoki pozwolą ci skonfigurować połączenia między tymi uchwytami a określonymi plikami i / lub urządzeniami (lub nawet potokami do innych procesów) przed rozpoczęciem procesu (niektóre z możliwe manipulacje są dość sprytne).Przykładem jest:
które będą:
my_prog
.inputfile
jako standardowe wejście (uchwyt pliku 0).errorfile
jako standardowy błąd (uchwyt pliku 2).grep
.my_prog
do standardowego wejściagrep
.Re twój komentarz:
To dlatego, że nie są normalnymi plikami. Podczas gdy UNIX prezentuje gdzieś wszystko jako plik w systemie plików, nie robi to tak na najniższych poziomach. Większość plików w
/dev
hierarchii to urządzenia znakowe lub blokowe, w rzeczywistości sterownik urządzenia. Nie mają rozmiaru, ale mają główny i mniejszy numer urządzenia.Po ich otwarciu następuje połączenie ze sterownikiem urządzenia, a nie z plikiem fizycznym, a sterownik urządzenia jest wystarczająco inteligentny, aby wiedzieć, że osobne procesy powinny być obsługiwane osobno.
To samo dotyczy systemu
/proc
plików Linux . To nie są prawdziwe pliki, tylko ściśle kontrolowane bramy do informacji jądra.źródło
xyz >xyz.out
zapisze twoje standardowe wyjście w fizycznym pliku, który może być odczytany przez inne procesy.xyz | grep something
połączyxyz
stdout zegrep
stdin bardziej bezpośrednio. Jeśli chcesz mieć nieograniczony dostęp do procesu, którego nie kontrolujesz w ten sposób, musisz zajrzeć do czegoś takiego/proc
lub napisać kod, aby przefiltrować dane wyjściowe, w jakiś sposób podpinając się do jądra. Mogą istnieć inne rozwiązania, ale wszystkie są prawdopodobnie tak samo niebezpieczne :-)/dev/stdin
jest to dowiązanie symboliczne/proc/self/fd/0
- pierwszy deskryptor pliku, który ma aktualnie uruchomiony program. To, na co wskazuje/dev/stdin
, zmieni się z programu na program, ponieważ/proc/self/
zawsze wskazuje na „aktualnie uruchomiony program”. (Niezależnie od tego, który program wykonujeopen
wywołanie)./dev/stdin
I przyjaciele zostali tam umieszczeni, aby uczynić skrypty powłoki setuid bezpieczniejszymi, i pozwolić przekazać nazwę pliku/dev/stdin
do programów, które działają tylko z plikami, ale chcesz kontrolować bardziej interaktywnie. (Pewnego dnia będzie to przydatna sztuczka, którą warto poznać.)Bardziej poprawne byłoby powiedzenie tego
stdin
,stdout
istderr
są to „strumienie we / wy”, a nie pliki. Jak zauważyłeś, te podmioty nie istnieją w systemie plików. Ale filozofia uniksowa, jeśli chodzi o I / O, to „wszystko jest plikiem”. W praktyce, to naprawdę oznacza, że można wykorzystać te same funkcje i interfejsy (bibliotekaprintf
,scanf
,read
,write
,select
, itd.), Nie martwiąc się o to, czy strumień I / O jest podłączony do klawiatury, plik na dysku, gniazda, rury, lub inna abstrakcja we / wy.Większość programów trzeba czytać wejścia, wyjścia i błędów zapisu dziennika, tak
stdin
,stdout
istderr
są predefiniowane dla ciebie, dla wygody programowania. Jest to tylko konwencja i nie jest egzekwowana przez system operacyjny.źródło
Jako uzupełnienie powyższych odpowiedzi, oto podsumowanie dotyczące przekierowań:
EDYCJA: Ta grafika nie jest całkowicie poprawna, ale nie jestem pewien, dlaczego ...
Grafika mówi, że 2> i 1 ma taki sam efekt jak &>
źródło
Obawiam się, że twoje zrozumienie jest całkowicie wstecz. :)
Pomyśl o „standardowym wejściu”, „standardowym wyjściu” i „standardowym błędzie” z perspektywy programu , a nie z perspektywy jądra.
Gdy program musi wydrukować dane wyjściowe, zwykle drukuje na „standardowe wyjście”. Program zwykle drukuje dane wyjściowe na standardowe wyjście, przy
printf
czym drukuje TYLKO na standardowe wyjście.Gdy program musi wydrukować informacje o błędzie (niekoniecznie wyjątki, są to konstrukcje języka programowania, narzucone na znacznie wyższym poziomie), zwykle drukuje na „błędzie standardowym”. Zwykle robi to za pomocą
fprintf
, który akceptuje strumień plików do użycia podczas drukowania. Strumieniem plików może być dowolny plik otwarty do zapisu: standardowe wyjście, błąd standardowy lub dowolny inny plik otwarty za pomocąfopen
lubfdopen
.„standardowe wejście” jest używane, gdy plik musi odczytać dane wejściowe, używając
fread
lubfgets
, lubgetchar
.Każdy z tych plików można łatwo przekierować z powłoki, tak jak to:
Lub cała enchilada:
Istnieją dwa ważne zastrzeżenia: po pierwsze, „standardowe wejście”, „standardowe wyjście” i „standardowy błąd” to tylko konwencja. Są to bardzo mocna konwencja, ale wszystko jest tylko zgodą, że bardzo miło jest móc uruchamiać programy w ten sposób:
grep echo /etc/services | awk '{print $2;}' | sort
i mieć standardowe wyjścia każdego programu podłączone do standardowego wejścia następnego programu w potoku.Po drugie, podałem standardowe funkcje ISO C do pracy ze strumieniami plików (
FILE *
obiektami) - na poziomie jądra są to wszystkie deskryptory plików (int
odniesienia do tabeli plików) oraz operacje na niższych poziomach, takie jakread
iwrite
, które nie wykonaj szczęśliwe buforowanie funkcji ISO C. Pomyślałem, że będę prostszy i używał łatwiejszych funkcji, ale pomyślałem, że mimo wszystko powinieneś znać alternatywy. :)źródło
standardowe
Czyta dane wejściowe przez konsolę (np. Klawiatura). Używany w C z scanf
standardowe
Generuje dane wyjściowe do konsoli. Używany w C z printf
stderr
Generuje wyjście „błędu” do konsoli. Używany w C z fprintf
Przekierowanie
Źródło stdin można przekierować. Na przykład, zamiast pochodzić z klawiatury, może pochodzić z pliku (
echo < file.txt
) lub innego programu (ps | grep <userid>
).Miejsca docelowe dla stdout, stderr można również przekierować. Na przykład stdout może zostać przekierowany do pliku:
ls . > ls-output.txt
w tym przypadku dane wyjściowe są zapisywane w plikuls-output.txt
. Stderr można przekierować za pomocą2>
.źródło
Myślę, że ludzie mówią, że
stderr
powinny być używane tylko do komunikatów o błędach, są mylące.Powinien być również używany do komunikatów informacyjnych, które są przeznaczone dla użytkownika uruchamiającego polecenie, a nie dla potencjalnych dalszych użytkowników danych (tj. Jeśli uruchomisz potok powłoki łączący kilka poleceń, nie chcesz komunikatów informacyjnych, takich jak „pobranie pozycji 30 z 42424 ”, aby pojawił się na
stdout
ekranie, ponieważ wprowadzą konsumenta w błąd, ale nadal możesz chcieć, aby użytkownik je zobaczył.Zobacz to dla uzasadnienia historycznego:
źródło
Użycie ps -aux ujawnia bieżące procesy, z których wszystkie są wymienione w / proc / as / proc / (pid) /, wywołując cat / proc / (pid) / fd / 0 wypisuje wszystko, co znajduje się na standardowym wyjściu myślę, że ten proces. Więc może,
/ proc / (pid) / fd / 0 - Standardowy plik wyjściowy
/ proc / (pid) / fd / 1 - Standardowy plik wejściowy
/ proc / (pid) / fd / 2 - Standardowy plik błędu
na przykład
Ale działało to dobrze tylko w przypadku / bin / bash, inne procesy na ogół nie miały nic w 0, ale wiele z nich miało błędy zapisane w 2
źródło
Aby uzyskać wiarygodne informacje o tych plikach, sprawdź strony podręcznika man, uruchom polecenie na swoim terminalu.
Ale dla prostej odpowiedzi każdy plik służy do:
standardowe wyjście dla strumienia wyjściowego
standardowe wejście strumienia
stderr do drukowania błędów lub komunikatów w dzienniku.
Każdy program uniksowy ma każdy z tych strumieni.
źródło
stderr nie będzie buforował pamięci podręcznej IO, więc jeśli nasza aplikacja będzie musiała wydrukować krytyczne informacje o wiadomościach (niektóre błędy, wyjątki) na konsolę lub do pliku, użyj go, gdy używasz standardowego wyjścia do drukowania ogólnych informacji dziennika, ponieważ używa buforowania IO Cache, istnieje szansa, że przed zapisaniem naszych wiadomości do aplikacji plikowej może się zamknąć, pozostawiając skomplikowane debugowanie
źródło
Plik z powiązanym buforowaniem nazywany jest strumieniem i deklarowany jako wskaźnik do zdefiniowanego typu PLIK. Funkcja fopen () tworzy pewne dane opisowe dla strumienia i zwraca wskaźnik do oznaczenia strumienia we wszystkich dalszych transakcjach. Zwykle istnieją trzy otwarte strumienie ze stałymi wskaźnikami zadeklarowanymi w nagłówku i powiązanymi ze standardowymi otwartymi plikami. Podczas uruchamiania programu trzy strumienie są wstępnie zdefiniowane i nie muszą być jawnie otwierane: standardowe wejście (do odczytu konwencjonalnego wejścia), standardowe wyjście (do zapisu konwencjonalnego wyjścia) i standardowy błąd (do zapisu wyjścia diagnostycznego). Po otwarciu standardowy strumień błędów nie jest w pełni buforowany; standardowe strumienie wejściowe i wyjściowe są w pełni buforowane wtedy i tylko wtedy, gdy można ustalić, że strumień nie odnosi się do urządzenia interaktywnego
https://www.mkssoftware.com/docs/man5/stdio.5.asp
źródło