Załóżmy, że infile zawiera określony tekst, i miałem wykonać następujący zestaw poleceń:
exec
3<infile
cat -n
<&3
cat -n
<&3
Pierwsza instancja cat wyświetli zawartość pliku, ale po raz drugi nic nie robi. Dlaczego się różnią?
źródło
Załóżmy, że infile zawiera określony tekst, i miałem wykonać następujący zestaw poleceń:
exec
3<infile
cat -n
<&3
cat -n
<&3
Pierwsza instancja cat wyświetli zawartość pliku, ale po raz drugi nic nie robi. Dlaczego się różnią?
Wyglądają jak to samo polecenie, ale różnią się tym, że stan systemu zmienił się w wyniku pierwszego polecenia. W szczególności pierwszy cat
zużył cały plik, więc drugi cat
nie ma już nic do przeczytania, natychmiast uderza EOF (koniec pliku) i kończy działanie.
Powodem tego jest to, że używasz dokładnie tego samego opisu pliku (tego, który utworzyłeś exec < infile
i przypisałeś do deskryptora pliku 3
) dla obu wywołań cat
. Jedną z rzeczy związanych z otwartym opisem pliku jest przesunięcie pliku. Tak więc pierwszy cat
odczytuje cały plik, pozostawia przesunięcie na końcu, a drugi próbuje odebrać od końca pliku i nie znajduje nic do przeczytania.
Aby dodać do dobrej odpowiedzi @ jw013, może pomóc uświadomić sobie, że jest taki sam jak
{
cat -n
cat -n
} < infile
< file
krótko mówiąc 0< file
, to znaczy użyj deskryptora pliku 0 zamiast 3.
I tylko trochę pomieszać sprawę, ta wersja:
exec 3< infile
cat -n /dev/fd/3
cat -n /dev/fd/3
Zachowuje się różnie w zależności od systemu operacyjnego uruchomionego go i typu z infile
(zwykły plik rury vs vs urządzenia ...)
W Solarisie i większości komercyjnych Unices, a open("/dev/fd/3")
jest mniej więcej równoważne dup(3)
(tak < /dev/fd/3
jest mniej więcej tak samo <&3
), podczas gdy w Linuksie, dla zwykłych plików, /dev/fd/3
jest implementowane jako symlink do oryginalnego pliku, więc open("/dev/fd/3")
otwiera go od nowa ( i ewentualnie z innymi flagami od fd 3).