Cosa è archiviato nei file / dev / pts e possiamo aprirli?


73

Secondo le mie conoscenze, i /dev/ptsfile vengono creati per sessioni ssh o telnet.


6
echo Hello > /dev/pts/1... Guarda cosa succede, è il tuo terminale.
Sepahrad Salour,


1
@SepahradSalour uno deve adattare il numero di punti al suo contesto. my sshd ha usato / dev / pts / 30 per la mia sessione.
Gab 是 好人

2
@Gab 是 好人 Per ottenere la posizione del tuo terminale corrente, puoi usare il comando tty.
JeromeJ,

Risposte:


110

Non viene archiviato nulla /dev/pts. Questo filesystem vive esclusivamente nella memoria.

Le voci in /dev/ptssono pseudo-terminali (in breve pty). I kernel Unix hanno una nozione generica di terminali . Un terminale consente alle applicazioni di visualizzare l'output e di ricevere input tramite un dispositivo terminale . Un processo può avere un terminale di controllo : per un'applicazione in modalità testo, è così che interagisce con l'utente.

I terminali possono essere terminali hardware ("tty", abbreviazione di "teletype") o pseudo-terminali ("pty"). I terminali hardware sono collegati tramite un'interfaccia come una porta seriale ( ttyS0, ...) o USB ( ttyUSB0, ...) o tramite uno schermo e una tastiera per PC ( tty1, ...). Gli pseudo-terminali sono forniti da un emulatore di terminale, che è un'applicazione. Alcuni tipi di pseudo-terminali sono:

  • Le applicazioni della GUI come xterm, gnome-terminal, konsole, ... trasformano gli eventi della tastiera e del mouse in input di testo e visualizzano graficamente l'output in alcuni font.
  • Applicazioni multiplexer come input e output di relè schermo e tmux da e verso un altro terminale, per separare le applicazioni in modalità testo dal terminale reale.
  • Applicazioni shell remote come sshd, telnetd, rlogind, ... inoltra input e output tra un terminale remoto sul client e un pty sul server.

Se un programma apre un terminale per la scrittura, l'output di quel programma appare sul terminale. È comune avere diversi programmi in uscita su un terminale allo stesso tempo, anche se a volte questo può creare confusione poiché non c'è modo di dire quale parte dell'output provenga da quale programma. I processi in background che tentano di scrivere sul proprio terminale di controllo possono essere automaticamente sospesi da un segnale SIGTTOU .

Se un programma apre un terminale per la lettura, l'input dell'utente viene passato a quel programma. Se più programmi leggono dallo stesso terminale, ciascun carattere viene instradato indipendentemente a uno dei programmi; questo non è raccomandato. Normalmente esiste un solo programma che legge attivamente dal terminale in un determinato momento; i programmi che tentano di leggere dal proprio terminale di controllo mentre non sono in primo piano vengono automaticamente sospesi da un segnale SIGTTIN .

Per sperimentare, esegui ttyun terminale per vedere qual è il dispositivo terminale. Diciamo che lo è /dev/pts/42. In una shell in un altro terminale, eseguire echo hello >/dev/pts/42: la stringa helloverrà visualizzata sull'altro terminale. Ora esegui cat /dev/pts/42e digita l'altro terminale. Per uccidere quel catcomando (che renderà difficile usare l'altro terminale), premi Ctrl+ C.

Scrivere su un altro terminale è talvolta utile per visualizzare una notifica; per esempio il writecomando lo fa. La lettura da un altro terminale non viene normalmente eseguita.


O sto fraintendendo quello che stai cercando di dire, o le tue informazioni sono spente. I processi in background che scrivono sul terminale non comporteranno un SIGTTIN. Né più programmi possono leggere dal terminale contemporaneamente (la tua affermazione che "ogni personaggio viene instradato in modo indipendente"). Solo un programma può leggere dal terminale in qualsiasi momento e un tentativo da parte di un programma in background di leggere da quel terminale comporterà un SIGTTIN. Questo è l'unico caso in cui SIGTTIN viene inviato automaticamente.
Patrick,

Inoltre non è possibile leggere neanche da un altro terminale. Fare ciò sarebbe una significativa vulnerabilità della sicurezza in quanto si sarebbe in grado di intercettare i dati. È possibile inserire straceil programma in lettura, ma è quello.
Patrick,

4
@Patrick I processi in background che scrivono sul terminale ottengono SIGTTOU, che era un errore di battitura. Più programmi possono leggere dal terminale contemporaneamente (provalo e vedi, come descrivo nel prossimo paragrafo; devi farlo da un processo il cui terminale di controllo non è quel terminale). Sì, puoi leggere da un altro terminale, purché appartenga a te - perché pensi che sarebbe impossibile?
Gilles 'SO- smetti di essere malvagio' il

I processi in background che scrivono sul terminale ottengono SIGTTOU solo se tostopè impostato il flag tty. Questo flag non è impostato per impostazione predefinita. E resto corretto sulla lettura dall'anoter TTY. L'ho provato e funziona, ma è basato su una lettura, non su una base per carattere (quando sono seduti al prompt della shell sono gli stessi che le shell leggono 1 carattere alla volta). Potrebbe essere utile chiarire questo punto, poiché è così che ho interpretato la tua risposta.
Patrick,

2
@Patrick Certo, una readchiamata restituirà solo caratteri consecutivi (o piuttosto byte, dovrei dire), ma l'applicazione non ha alcun controllo su quanti byte readrestituirà una chiamata, quindi non è migliore.
Gilles 'SO- smetti di essere malvagio' il

18

I file in /dev/ptssono "pseudo-ttys". Sono come i tubi denominati in una certa misura, ma imitano anche i vecchi terminali di connessione seriale, come i VT-100. Gli pseudo-tty svolgono il lavoro di trasferimento di byte dalla tastiera al programma e dal programma al dispositivo di output, il che sembra semplice. Ma questo risponde alla tua domanda esplicita: il kernel non memorizza nulla /dev/pts/0per esempio. Solo flussi di byte provenienti dallo stdout di un programma collegato alla pseudo-tty entrano e i programmi il cui stdin è collegato alla stessa pseudo-tty leggono quei byte.

Gli pseudo-tty mettono anche uno strato di indiretta in quei flussi di byte. Il kernel può ispezionare i byte alla ricerca di valori speciali come "Control-C" o "Control-D" o "Control-U" (che sono tutti configurabili, vedi man stty) e inviare un SIGINT, impostare la fine del file su stdin o cancellare una riga sull'ingresso. C'è anche una funzione di buffering da qualche parte, quindi il mio "non memorizza nulla" è in qualche modo sbagliato, ma solo di pochi kilobyte.

Il kernel può ispezionare i valori dei byte in uscita e fare cose come trasformare una nuova riga (avanzamento di riga ASCII, LF o "\n") in due byte, ritorno a capo e avanzamento di riga (CRLF o "\r\n"), o qualsiasi byte richiesto dall'hardware di un terminale seriale. L'indirizzamento indiretto di una pseudo-tty consente l'indipendenza dall'hardware.

Gli pseudo-tty consentono anche tutto il "set baud rate", "set parity" e così via ioctl()chiamate di sistema, e probabilmente non fanno nulla con loro. In questo modo i programmi che sono stati riscritti ai tempi dei VT-100s, ADM-3 e Wysevers continuano a funzionare senza errori. Il software, il driver di dispositivo pseudo-ttys, si comporta come hardware.

Gli pseudo-tty possono essere usati da sshde telnet, ma sono anche usati tra un emulatore di terminale (come xtermo rxvt) e la shell che generalmente gira all'interno di xterm.

Linux e molti Unix hanno pseudo-tty. Il piano 9 no. Gli pseudo-tty sono un po 'una reliquia, lasciati dai tempi dei terminali hardware collegati via cavo seriale.


13

/dev/è una directory speciale per i file del dispositivo. Queste sono astrazioni, non sono file reali su disco. La directory è popolato in fase di avvio e soggetti a modifiche per riflettere interfacce dei dispositivi esistenti, che vengono creati e distrutti dal kernel e un demone userspace, udevd.

Molti dei dispositivi così rappresentati sono virtuali. Ciò include le voci in /dev/pts, che sono dispositivi console. Questo è il motivo per cui uno è stato creato per sessioni remote; vengono anche creati quando si apre un terminale GUI locale.

Puoi aprirli come file, anche se non ha molto valore d'uso. Per ottenere il /dev/ptsnodo a cui è connessa la shell, utilizzare tty:

> tty
/dev/pts/4

Ora passa ad un'altra console e prova:

> echo "duck!" > /dev/pts/4

Intelligente. Ora prova:

> cat /dev/pts/4

Quindi prova a usare la shell in / dev / pts / 4. Rimani bloccato finché non esci catdall'altra parte, ma la maggior parte di ciò che digiti su pts / 4 passerà attraverso (ad esempio provando "ciao mondo" ho finito con hlsu pts / 4 e ello wordsulla catconsole).

La mia ipotesi qui è che il dispositivo stia ricevendo input dalla shell e li emetta tramite il sistema, ed è così che le cose finiscono sullo schermo - la shell non ha a che fare con l'hardware, il sistema lo è. Prova strace bash(e dai un'occhiata man stracese non sai di cosa si tratta); ricevi una raffica preliminare di chiamate all'avvio di bash. Ora inizia a premere i tasti:

read(0, "h", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "h", 1h)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "e", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "e", 1e)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "y", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "y", 1y)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0

Per ogni lettera digitata c'è una lettura dallo standard input e una scrittura nello standard out. Ma a cosa è collegato lo standard della shell? Ora prova stracesul tuo terminale GUI: dovrai capire il nome se non lo conosci, ad es. Su KDE è konsole, e GNOME ha gnome-terminal, credo. L'output di questo straceè probabilmente più criptico - il mio ha un sacco di poll()e recvfrom(). Non vedo alcuna scrittura, ma se ora tiri il cattrucco da un altro terminale, noterai quando digiti, i tasti premuti che vengono letti da cat non causano alcuna risposta nell'output di strace - il terminale non è ' li ricevono. Quindi l'app del terminale della GUI e il gatto sono in competizione per leggere dallo stesso dispositivo, in cui la shell sta eseguendo l'output.


a che serve 'cat / dev / pts / 4' quando siamo bloccati e perché stiamo bloccando mentre eseguiamo questo comando.
user2720323

Ho aggiunto alcuni paragrafi per cercare di spiegare questo.
Riccioli d'oro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.