Solo una nota in più sulle ottime risposte che sono già state fornite. Si noti che [ -t 0 ]
verifica che il descrittore di file 0 sia aperto in un file che è un file di dispositivo con una disciplina tty line (in genere, ciò viene fatto controllando che un innocuo termio (s) ioctl () abbia successo).
Inoltre, ciò non significa necessariamente che ci sia un emulatore di terminale o terminale (con un vero utente che digita su una tastiera) dall'altra parte (anche se nella stragrande maggioranza dei casi e probabilmente la maggior parte di quelli a cui tieni, è abbastanza buono un approssimazione).
I dispositivi tty e pty possono anche essere utilizzati per il trasferimento di dati o come meccanismo di comunicazione tra processi.
Ad esempio, si potrebbe fare:
(stty raw -echo; myscript) < /dev/ttyS0
Per alimentare ciò che viene ricevuto tramite RS232 a myscript
.
echo test | ssh -tt host myscript
lo myscript
stdin sarebbe un dispositivo pty (con sshd
dall'altra parte, ed eventualmente (attraverso la connessione ssh) non un terminale, ma un tubo alimentato da echo
)
Per verificare ulteriormente che ci sia un terminale all'altra estremità di quella linea o pty RS232, puoi anche verificare che una $TERM
variabile sia impostata e non vuota ( [ -n "$TERM" ]
) e inviare una sequenza di escape del rapporto sullo stato del dispositivo su quella fd e verificare che tu riceva una risposta (oltre a [ -t 0 ]
e [ -n "$TERM" ]
).
printf >&0 '\e[5n'
Viene risposto con a \e[0n
dalla maggior parte dei terminali.
Ora ci sono diversi problemi con questo, quindi non consiglierei di farlo tranne nel caso in cui desideri verificarlo perché vuoi eseguire un'applicazione TUI visiva (nel qual caso, sarebbe meglio usare librerie come ncurses
, e invece del DSR, preferiresti inviare una sequenza di escape di identificazione del dispositivo per interrogare il tipo di terminale in modo più preciso che via $TERM
):
- Per fortuna, nella maggior parte dei casi in cui stdin non è un terminale, sarà stato aperto in modalità di sola lettura, il che causerebbe un
printf
errore, ma nel caso in cui stdin sia un dispositivo tty aperto in modalità lettura + scrittura, ciò avrà l'effetto collaterale di inviare quella sequenza all'altro capo. Ad esempio nel nostro esempio di ssh sopra, che effettivamente invierà la sequenza a un terminale (ma la risposta non arriverà su stdin)
- È difficile leggere la risposta in modo affidabile e portabile. Dovresti cambiare temporaneamente la disciplina della linea tty e leggere un byte alla volta. Dovrai anche decidere un timeout entro il quale se la risposta non viene visualizzata, ti arrendi e decidi che non esiste un terminale. Se si desidera prendere in considerazione le persone che effettuano la chiamata tramite connessioni satellitari, ciò significa un lungo timeout.
- Leggere da un terminale in background sospenderebbe il tuo script con un segnale SIGTTIN.