Jak czytać / zapisywać na urządzeniu tty *?


29

Mam urządzenie, które wysyła informacje przez USB do mojego komputera. Arch Linux konfiguruje to urządzenie, tworząc plik o nazwie ttyUSB0w /dev/. Używałem GTKtermdo odbierania tych przychodzących informacji i wyświetlania ich w emulowanym oknie terminala.

Moje pytanie brzmi: jak dokładnie GTKtermodczytuje / zapisuje ten ttyUSB0plik i gdzie mogę zacząć uczyć się, jak wdrażać podobną funkcjonalność? To znaczy, w najbardziej podstawowej formie, w jaki sposób mogę napisać znak ttyUSB0lub, przeciwnie, otrzymać bajt i zapisać go do pliku?


1
Spróbuj użyć kota do czytania, a echo do pisania. „Wszystko jest plikiem” w
Uniksie

Możesz spróbować otworzyć na nim konsolę szeregową. screenmoże to zrobić, iminiterm
mikeserv

Myślałem o podejściu programowym. Jeśli to prawda i jest to naprawdę takie łatwe (wystarczy otworzyć i odczytać plik), czy po prostu napiszesz nieskończoną pętlę, aby stale otwierać, czytać, zamykać plik i aktualizować, gdy nowe dane są obecne od poprzedniego czasu? Co się stanie, jeśli urządzenie „tty” spróbuje zapisać plik, jeśli jest on otwarty w programie?
sherrellbc

Może to pomóc: cmrr.umn.edu/~strupp/serial.html : open (), read (), write () i select (). Wydaje się, że to nic specjalnego.
dchirikov

@sherrellbc - możesz pisać screeni / lub minitermprogramować.
mikeserv

Odpowiedzi:


38

Pliki TTY to pliki, których można używać tak samo jak każdego innego. Możesz je otworzyć za pomocą standardowych narzędzi do otwierania plików w swoim języku i czytać lub pisać z nich. Mają pewne specjalne zachowanie, które różni się od „zwykłych” plików, ale podstawy są takie same. Na końcu omówię kilka specjalnych przypadków, ale najpierw eksperyment.

Jedną interesującą rzecz, którą możesz zrobić bezpośrednio ze zwykłego terminala. Uruchom, ttya wyświetli wiersz:

/dev/pts/2

To urządzenie TTY, na którym działa terminal. Możesz coś napisać na tym terminalu:

$ echo Hello > /dev/pts/2
Hello
$

Możesz nawet przeczytać z niego:

$ read X < /dev/pts/2
hello
$ echo $X
hello
$

( read Xto polecenie sh „odczytuje wiersz ze standardowego wejścia do zmiennej X”; <ma używać / dev / pts / 2 jako standardowego wejścia dla polecenia read; pierwsze „hello” wpisałem, a drugie zostało wydrukowane) .

Jeśli otworzysz inną powłokę, powiedzmy za pomocą screenlub xterm, możesz uruchomić echo spooky > /dev/pts/2w tej powłoce, aby tekst pojawił się na oryginalnym terminalu, i to samo dla innych poleceń. Wszystko to jest tylko twoją powłoką otwierającą plik bez wiedzy, że jest to TTY.


Oto bardzo prosty program C, który robi dokładnie to, o co prosiłeś, i zapisuje pojedynczy znak do / dev / pts / 3, a następnie odczytuje z niego pojedynczy bajt:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>    
int main() {
    char byte;
    int fd = open("/dev/pts/3", O_RDWR);
    write(fd, "X", 1);
    ssize_t size = read(fd, &byte, 1);
    printf("Read byte %c\n", byte);
    return 0;
}

Prawdziwe urządzenie TTY, które jest podłączone do emulatora powłoki lub terminala, będzie miało tam ciekawe zachowanie, ale powinieneś coś odzyskać.


Aby uzyskać dostęp do terminala, musisz mieć pozwolenie na jego użycie. Są to tylko standardowe uprawnienia do plików, które widzisz ls -li ustawiasz za pomocą chmod: musisz mieć uprawnienia do odczytu, aby otworzyć plik i odczytać, oraz uprawnienia do zapisu, aby do niego zapisać. TTY, które wspierają terminal, będą własnością użytkownika, ale TTY innego użytkownika nie, a TTY na urządzenia USB mogą, ale nie muszą, w zależności od konfiguracji. Możesz zmienić uprawnienia w taki sam sposób, jak zawsze.

Jeśli chodzi o pisanie programu do pracy z nim, nie musisz robić nic specjalnego. W tym przykładzie widać, że jedną rzeczą, której nie trzeba robić, jest zamykanie pliku za każdym razem, aby dane były odczytywane przez drugi koniec: pliki TTY działają jak potoki, popychając dane w obu kierunkach, gdy tylko nadchodzą. Kiedy napisałem tekst do TTY, pojawił się natychmiast, a kiedy go przeczytałem, nic już na mnie nie czekało. To nie jest jak zapisywanie do zwykłego pliku, w którym dane są zapisywane na dysku - są one natychmiast przekazywane na drugą stronę lub przechowywane w pamięci, dopóki ktoś ich nie przeczyta.

Możesz użyć funkcji wyboru , abyś mógł robić inne rzeczy, czekając, aż urządzenie coś powie, ale jeśli z przyjemnością zaczekasz na dane, możesz po prostu zablokować odczyty i pozwolić systemowi operacyjnemu zrobić podnoszenie.

Jedną z rzeczy, o których należy pamiętać, jest to, że w jądrze może być ograniczony rozmiar bufora, a jeśli napiszesz dużo danych naraz, możesz zablokować się bez sensu. Jeśli może to stanowić problem, użyj nieblokującego We / Wy z open("/dev/...", O_RDWR | O_NONBLOCK). W obu przypadkach zasada będzie taka sama.


Próbuję, sudo echo Hello > /dev/tty4gdy jestem w środowisku pulpitu, ale dostaję, bash: /dev/tty4: Permission deniedjeśli nie jestem zalogowany do tty4. Jednak jeśli jestem zalogowany do tty4, wszystko działa dobrze. Jaki jest tego powód?
Utku

@Utku, To z pewnością jakiś problem z uprawnieniami, które są usuwane po uwierzytelnieniu w terminalu wirtualnym. Sprawdź uprawnienia do plików przed i po zalogowaniu.ls -l /dev/tty4
sherrellbc

1
> /dev/tty4część ist nie częścią echopodproces rozpoczętej przez sudoale część sudosamego procesu, który jest wykonywany przez bieżącego użytkownika. zamiast roota mają zastosowanie uprawnienia do pliku dla bieżącego użytkownika.
Robin479,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.