Làm thế nào để đọc / ghi vào thiết bị tty *?


29

Tôi có một thiết bị gửi thông tin qua USB đến máy tính của tôi. Arch Linux thiết lập thiết bị này bằng cách tạo một tệp có tên ttyUSB0trong /dev/. Tôi đã và đang sử dụng GTKtermđể nhận thông tin đến này và hiển thị nó trong một cửa sổ đầu cuối mô phỏng.

Câu hỏi của tôi là, chính xác làm thế nào để GTKtermđọc / ghi vào ttyUSB0tệp này và tôi có thể bắt đầu học cách thực hiện chức năng tương tự ở đâu? Đó là, ở dạng cơ bản nhất, làm thế nào tôi có thể viết một ký tự ttyUSB0, hoặc ngược lại, nhận một byte và ghi nó vào một tệp?


1
Cố gắng sử dụng con mèo để đọc và tiếng vang để viết. "Mọi thứ là một tập tin" trong unix :)
dchirikov

Bạn có thể thử mở một giao diện điều khiển nối tiếp trên nó. screencó thể làm điều này, vàminiterm
mikeerv

Tôi đã suy nghĩ theo cách tiếp cận theo chương trình. Nếu điều này là đúng và nó thực sự dễ dàng (chỉ cần mở và đọc tệp), bạn có thể viết một vòng lặp vô hạn để liên tục mở, đọc, đóng tệp và cập nhật khi có dữ liệu mới từ lần trước không? Điều gì xảy ra nếu thiết bị 'tty' cố ghi vào tệp nếu bạn mở nó trong chương trình của mình?
sherrellbc

Có thể nó giúp: cmrr.umn.edu/~strupp/serial.html : open (), read (), write () và select (). Không có gì đặc biệt, có vẻ như.
dchirikov

@sherrellbc - bạn có thể viết kịch bản screenvà / hoặc minitermlập trình.
mikeerv

Câu trả lời:


38

TTY là các tệp mà bạn có thể sử dụng giống như bất kỳ tệp nào khác. Bạn có thể mở chúng bằng các công cụ mở tệp tiêu chuẩn của ngôn ngữ của bạn và đọc hoặc viết từ chúng. Họ có một số hành vi đặc biệt khác với các tệp "thông thường", nhưng những điều cơ bản là giống nhau. Tôi sẽ đề cập đến một số trường hợp đặc biệt ở cuối, nhưng trước tiên, một thử nghiệm.

Một điều thú vị bạn có thể làm trực tiếp từ một thiết bị đầu cuối thông thường. Chạy ttyvà nó sẽ in một dòng như:

/dev/pts/2

Đó là thiết bị TTY mà thiết bị đầu cuối của bạn đang chạy. Bạn có thể viết một cái gì đó cho thiết bị đầu cuối đó:

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

Bạn thậm chí có thể đọc từ nó:

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

( read Xlà lệnh "đọc một dòng từ đầu vào tiêu chuẩn thành biến X" của sh; .

Nếu bạn mở một shell khác, giả sử bằng cách sử dụng screenhoặc xterm, bạn có thể chạy run echo spooky > /dev/pts/2trong shell đó để làm cho văn bản xuất hiện trên thiết bị đầu cuối ban đầu của bạn và tương tự cho các lệnh khác. Tất cả điều này chỉ là vỏ của bạn mở một tệp mà không biết đó là TTY.


Đây là một chương trình C rất đơn giản, thực hiện đúng những gì bạn đã hỏi và viết một ký tự đơn vào / dev / pts / 3, sau đó đọc một byte đơn từ nó:

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

Một thiết bị TTY thực được gắn vào trình giả lập vỏ hoặc thiết bị đầu cuối sẽ có hành vi thú vị ở đó, nhưng bạn nên lấy lại một cái gì đó.


Để truy cập một thiết bị đầu cuối, bạn cần có quyền sử dụng nó. Đó chỉ là các quyền của tệp tiêu chuẩn mà bạn thấy ls -lvà thiết lập với chmod: bạn cần có quyền đọc để mở tệp và đọc nó, và viết quyền để ghi vào đó. Các TTY quay lại thiết bị đầu cuối của bạn sẽ thuộc sở hữu của bạn, nhưng TTY của người dùng khác sẽ không và TTY cho các thiết bị USB có thể có hoặc không, tùy thuộc vào cấu hình của bạn. Bạn có thể thay đổi các quyền theo cùng một cách như mọi khi.

Theo như viết một chương trình để làm việc với nó, bạn không cần phải làm gì đặc biệt. Bạn có thể thấy trong ví dụ rằng một điều bạn không cần làm là đóng tệp mỗi lần để dữ liệu của bạn được đọc ở đầu bên kia: các tệp TTY hoạt động giống như các đường ống, chỉ cần đẩy dữ liệu theo cả hai hướng khi nó đi vào. Khi tôi viết văn bản cho TTY, nó xuất hiện ngay lập tức và khi tôi đọc nó từ đó thì không có gì chờ đợi tôi cả. Nó không giống như ghi vào một tệp thông thường nơi dữ liệu được lưu trên đĩa - nó được chuyển ngay lập tức sang phía bên kia hoặc được lưu trong bộ nhớ cho đến khi có ai đó đọc nó.

Bạn có thể muốn sử dụng chức năng chọn để bạn có thể làm những việc khác trong khi chờ thiết bị nói điều gì đó, nhưng nếu bạn vui lòng đợi dữ liệu đi qua, bạn có thể sử dụng chặn đọc và để HĐH thực hiện việc nâng.

Một điều cần lưu ý là có thể có kích thước bộ đệm hạn chế trong kernel và nếu bạn viết nhiều dữ liệu cùng một lúc, bạn có thể sẽ chặn mà không có ý nghĩa gì. Nếu đó có thể là một vấn đề, hãy sử dụng IO không chặn với open("/dev/...", O_RDWR | O_NONBLOCK). Nguyên tắc sẽ là một trong hai cách.


Tôi đang thử sudo echo Hello > /dev/tty4khi ở trong môi trường máy tính để bàn nhưng tôi nhận được bash: /dev/tty4: Permission deniednếu tôi không đăng nhập vào tty4. Tuy nhiên nếu tôi đăng nhập vào tty4, mọi thứ đều hoạt động tốt. Lý do cho điều này là gì?
Utku

@Utku, Đó chắc chắn là một số vấn đề về quyền được loại bỏ sau khi xác thực với thiết bị đầu cuối ảo. Kiểm tra quyền truy cập tệp trước và sau khi bạn đã đăng nhập.ls -l /dev/tty4
sherrellbc

1
các > /dev/tty4phần ist không nằm trong echotiến trình con bắt đầu bởi sudonhưng một phần của sudoquá trình tự, được thực hiện bởi người sử dụng hiện nay. quyền truy cập tệp cho người dùng hiện tại áp dụng thay vì root.
Robin479
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.