Як читати / записувати на tty * пристрій?


29

У мене є пристрій, який надсилає інформацію через USB на мій комп'ютер. Arch Linux налаштовує цей пристрій, створюючи файл з ім'ям ttyUSB0в /dev/. Я використовував GTKtermдля отримання цієї вхідної інформації та відображення її у емульованому вікні терміналу.

Моє запитання полягає в тому, як саме GTKtermчитати / записувати в цей ttyUSB0файл, і де я можу почати вчитися виконувати подібні функції? Тобто, в самому базовому вигляді, як я можу записати символ ttyUSB0або, навпаки, отримати байт і записати його у файл?


1
Спробуйте використовувати кішку для читання, а ехо - писати. "Все - файл" в unix :)
dchirikov

Ви можете спробувати відкрити на ньому послідовну консоль. screenможе це зробити, іminiterm
mikeserv

Я думав з точки зору програмного підходу. Якщо це правда, і це дійсно так просто (будучи просто відкривати та читати файл), ви б просто написати нескінченний цикл, щоб постійно відкривати, читати, закривати файл та оновлювати, коли нові дані з’являються з попереднього разу? Що станеться, якщо пристрій 'tty' намагається записати у файл, якщо він відкритий у вашій програмі?
sherrellbc

Можливо, це допоможе: cmrr.umn.edu/~strupp/serial.html : open (), read (), write () та select (). Нічого особливого, здається.
дчіріков

@sherrellbc - ви можете писати сценарії screenта / або minitermпрограматично.
mikeserv

Відповіді:


38

TTY - це файли, які ви можете використовувати, як і будь-який інший. Ви можете відкрити їх за допомогою стандартних інструментів для відкриття файлів вашої мови та читати чи писати з них. У них особлива поведінка, яка відрізняється від "звичайних" файлів, але основи однакові. Я висвітлю деякі особливі випадки наприкінці, але спочатку експеримент.

Одна цікава річ, яку ви можете зробити прямо зі звичайного терміналу. Виконати, ttyі він надрукує рядок на зразок:

/dev/pts/2

Це пристрій TTY, на якому працює ваш термінал. Ви можете написати щось на цьому терміналі:

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

Ви навіть можете прочитати з нього:

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

( read Xє команда "читати рядок зі стандартного вводу в змінну X"; <- використовувати / dev / pts / 2 як стандартний вхід для команди read; перший "привіт" я набрав, а другий був роздрукований) .

Якщо ви відкриєте іншу оболонку, скажімо, використовуючи screenабо xterm, ви можете запустити запустити echo spooky > /dev/pts/2в цій оболонці, щоб текст відображався на оригінальному терміналі, і те ж саме для інших команд. Все це лише ваша оболонка, яка відкриває файл, не знаючи, що це TTY.


Ось дуже проста програма C, яка робить саме те, що ви просили, і записує один символ у / dev / pts / 3, а потім зчитує з нього один байт:

#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;
}

Справжній пристрій TTY, приєднаний до емулятора оболонки або терміналу, матиме там цікаву поведінку, але вам слід щось повернути.


Для доступу до терміналу потрібно мати дозвіл на його використання. Це лише стандартні дозволи для файлів, з якими ви бачите ls -lта встановлені chmod: вам потрібен дозвіл на читання, щоб відкрити файл і прочитати його, а також надати дозвіл на запис у нього. TTY, які підтримують ваш термінал, належать вам, але TTY іншого користувача не буде, а TTY для USB-пристроїв можуть бути, а можуть і не бути, залежно від вашої конфігурації. Ви можете змінити дозволи так само, як завжди.

Що стосується написання програми для роботи з нею, то не потрібно робити особливих особливостей. Ви можете бачити на прикладі, що одне, що вам не потрібно робити, - це закривати файл кожного разу, щоб ваші дані були прочитані іншим кінцем: файли TTY діють як трубопроводи, просто висуваючи дані в обох напрямках, коли вони надходять. Коли я писав текст до TTY, він з’явився негайно, і коли я прочитав його, після цього мене вже нічого не чекало. Це не так, як писати в звичайний файл, де дані зберігаються на диску - вони передаються негайно на іншу сторону або зберігаються в пам'яті, поки хтось не прочитає їх.

Ви можете скористатися функцією вибору, щоб ви могли робити інші речі, поки ви будете чекати, коли пристрій щось скаже, але якщо ви з радістю просто дочекаєтесь отримання даних, ви можете просто заблокувати читання та дозволити операційній системі робити підйом.

Одне, що потрібно пам’ятати, - це те, що в ядрі може бути обмежений розмір буфера, і якщо ви записуєте багато даних одразу, ви можете в кінцевому підсумку блокувати без сенсу. Якщо це, ймовірно, є проблемою, використовуйте неблокуючий IO за допомогою open("/dev/...", O_RDWR | O_NONBLOCK). Принцип буде однаковим і в будь-якому випадку.


Я намагаюся, sudo echo Hello > /dev/tty4коли перебуваю в середовищі робочого столу, але отримую, bash: /dev/tty4: Permission deniedякщо я не ввійшов у tty4. Однак якщо я зареєстрований у tty4, все працює добре. У чому причина цього?
Утку

@Utku, це, безумовно, якась проблема дозволів, яка видаляється після аутентифікації з віртуальним терміналом. Перевірте дозволи на отримання файлів до та після входу.ls -l /dev/tty4
sherrellbc

1
> /dev/tty4частина IST НЕ є частина echoподпроцесса розпочатого , sudoале частиною sudoсамого процесу, який виконується для поточного користувача. дозволи для файлів для поточного користувача застосовуються замість root.
Robin479
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.