Przekierowanie wyjścia programu

11

Kiedy próbujesz przekierować wyjście programu za pomocą składni „jakaś liczba większa niż” (np. foo 2> myfile), Jakie są tutaj możliwe liczby i co one reprezentują?

Wierzę, że 1 to /dev/stdout2 to /dev/stderr. Co z 5 i 6? Czy jest 3, 4 lub jakaś liczba większa niż 6?

Student Fermata
źródło
Zobacz także Kiedy użyjesz dodatkowego deskryptora pliku?
Gilles „SO- przestań być zły”

Odpowiedzi:

11

Ten rzekomy program zapisze pod podanym przez ciebie deskryptorem pliku. rozważ następujący program witaj na świecie:

#include <stdio.h>

main()
{
   ssize_t i = 0 ;
   printf ("hello world\n") ;
   i = write( 5 , "Bonjour Monde\n", 14 ) ;
   printf ("%d octet dans 5\n", (int) i) ;
}

skompiluj to

me@mybox:~/tmp7$ make hw
cc     hw.c   -o hw

teraz prosty bieg

me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5

brak pliku dla 5, więc nie zapisano bajtu.

następna próba:

me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde

Udaje mi się uzyskać wynik, określając plik i deskryptor pliku (np 5>u.).

W praktyce, chyba że napisałeś tak zabawny program jak powyżej, jest mało prawdopodobne, aby gromadzić dane przy użyciu 5>foo.

w skrypcie powłoki konstrukcje przy użyciu <() są bardziej przydatne:

 diff <( cmd -par 1 ) <(cmd -par 2)
Archemar
źródło
write()zwraca ssize_tnie int.
Andrew Henle,
To nie jest główny punkt pytania, jest też zwrot dla funkcji printf.
Archemar
Nieużywanie zwracanej wartości różni się znacznie od używania niewłaściwego typu .
Andrew Henle
edytowane Nie widzę żadnych zmian w produkcji ...
Archemar
10

Liczby reprezentują deskryptory plików (uchwyty do plików, które zostały otwarte).

Powłoka zwykle ma 3 ustawione automatycznie,

0 - stdin 1 - stdout 2 - stderr

Ale można otwierać kolejne pliki i zwiększać liczby.

X Tian
źródło
7

Te liczby są deskryptorami plików . Jak zauważyłeś, istnieje kilka, które są tworzone automatycznie. Gdy inne pliki lub rzeczy podobne do plików zostaną otwarte, otrzymają inne numery.

Liczby używane w danym programie zależą od tego, jakie pliki zostały otwarte przez ten program lub w inny sposób wykorzystane. Na przykład, jeśli chcesz „zapisać” bieżący stdin i tymczasowo przekierować stdin z innego miejsca, a następnie przywrócić go później, możesz zrobić coś takiego:

exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate

Więc ten skrypt miałby 4deskryptor pliku dostępny przynajmniej przez jakiś czas. To 4 może być wszystkim, co nie jest używane (cóż, istnieje ograniczenie liczby plików, które proces może otworzyć, ale wszystko w tym limicie).

Możesz zobaczyć, jakie deskryptory plików otworzył proces i gdzie są one otwarte, zaglądając do /proc/<pid>/fd. Pokazuje wszystkie otwarte deskryptory plików dla tego procesu <pid>i pliki, z którymi są skojarzone.

Eric Renouf
źródło
0

Każdy proces otrzymuje liczby całkowite jako deskryptory plików, przy czym w POSIX są trzy zarezerwowane: 0 to stdin, 1 to stdout, a 2 to stderr. Do kolejnych plików zostaną przypisane kolejne numery. Możesz to łatwo sprawdzić za pomocą tego programu, zapisz go jako fdtest.c , aby mógł otworzyć swój własny kod programu podczas działania:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = open("fdtest.c", O_RDONLY);
    printf("%d\n", fd);
    close(fd);
    return 0;
}

Skompiluj to:

gcc fdtest.c -o fdtest

Uruchom:

./fdtest

Wynik, który otrzymasz, jest mniej więcej taki:

3

... który jest numerem deskryptora pliku, do którego odnosi się zmienna fd.

rexkogitans
źródło