Le specifiche POSIX coprono davvero le sue scommesse per quanto riguarda il Terminale di controllo , e che definisce così:
- Terminale di controllo
- La questione di quale dei diversi file speciali che si riferiscono al terminale potrebbe non essere affrontata in POSIX.1. Il nome percorso
/dev/tty
è sinonimo del terminale di controllo associato a un processo.
È nell'elenco delle definizioni e non c'è altro. Ma in General Terminal Interface , si dice ancora:
Un terminale può appartenere a un processo come suo terminale di controllo. Ogni processo di una sessione che ha un terminale di controllo ha lo stesso terminale di controllo. Un terminale può essere il terminale di controllo per al massimo una sessione. Il terminale di controllo per una sessione è assegnato dal leader della sessione in un modo definito dall'implementazione. Se un leader di sessione non ha un terminale di controllo e apre un file del dispositivo terminale che non è già associato a una sessione senza utilizzare l'opzione O_NOCTTY (vedere open ()), viene definito dall'implementazione se il terminale diventa il terminale di controllo della sessione capo.
Il terminale di controllo viene ereditato da un processo figlio durante una chiamata della funzione fork (). Un processo abbandona il suo terminale di controllo quando crea una nuova sessione con ilsetsid()
funzione; altri processi rimanenti nella vecchia sessione che aveva questo terminale poiché il suo terminale di controllo continua ad averlo. Alla chiusura dell'ultimo descrittore di file nel sistema (indipendentemente dal fatto che sia o meno nella sessione corrente) associato al terminale di controllo, non è specificato se tutti i processi che avevano quel terminale come terminale di controllo cessano di avere un terminale di controllo. Non è specificato se e come un leader di sessione possa riacquistare un terminale di controllo dopo che il terminale di controllo è stato abbandonato in questo modo. Un processo non abbandona il suo terminale di controllo semplicemente chiudendo tutti i suoi descrittori di file associati al terminale di controllo se altri processi continuano ad averlo aperto.
Ne rimangono molte cose non specificate - e onestamente penso che abbia senso. Mentre il terminale è un'interfaccia utente chiave, in alcuni casi è anche un sacco di altre cose - come l'hardware reale o persino un tipo di stampante - ma in molti casi non è praticamente nulla - come un xterm
che è solo un emulatore . È difficile essere specifici lì - e non penso che sarebbe comunque nell'interesse di Unix, perché i terminali fanno molto di più di Unix.
Comunque, POSIX è anche piuttosto incerto su come ps
dovrebbe comportarsi per quanto riguarda il ctty.
C'è l' -a
interruttore:
- Scrivi informazioni per tutti i processi associati ai terminali. Le implementazioni possono omettere i leader di sessione da questo elenco.
Grande. I leader della sessione possono essere omessi. Non è molto utile.
E -t
:
- Scrivi informazioni per i processi associati ai terminali indicati nella termlist. La domanda deve garantire che l'elenco di termini sia un singolo argomento sotto forma di un
<blank>
elenco separato da virgole. Gli identificativi dei terminali devono essere forniti in un formato definito dall'implementazione .
... che è un'altra delusione. Ma continua dicendo questo sui sistemi XSI:
- Sui sistemi conformi a XSI, devono essere indicati in una delle due forme: il nome del file del dispositivo (ad esempio,
tty04
) o, se il nome del dispositivo inizia con tty
, solo l'identificatore che segue i caratteri tty
(ad esempio 04
) .
È un po 'meglio, ma non è un percorso. Anche sui sistemi XSI c'è lo -d
switch:
- Scrivi informazioni per tutti i processi, tranne i leader della sessione.
... che è almeno chiaro. Puoi specificare anche l' -o
utput switch con la tty
stringa di formato, ma, come hai notato, il suo formato di output è definito dall'implementazione. Tuttavia, penso che sia bello come si arriva. Penso che - con un sacco di lavoro - gli interruttori di cui sopra in combinazione con alcune altre utility possano offrirti un campo da baseball abbastanza buono. Ad essere sincero, però, non so quando / come si rompe per te - e non sono stato in grado di immaginare una situazione in cui sarebbe. Ma probabilmente penso che aggiungiamo fuser
e find
possiamo verificare il percorso.
exec 2<>/dev/null
ctty=$(sh -c 'ps -p "$$" -o tty=' <&2)
sid=$(sh -c 'ps -Ao pid= -o tty=|
grep '"$ctty$"' |
grep -Fv "$(ps -do pid=)"' <&2)
find / -type c -name "*${ctty##*/}*" \
-exec fuser -uv {} \; 2>&1 |
grep ".*$ctty.*${sid%%"$ctty"*}"
Il /dev/null
materiale era solo per dimostrare che poteva funzionare quando nessuno dei sottotitoli di ricerca aveva uno di 0,1,2 collegato al ctty. Ad ogni modo, ciò stampa:
/dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh
Ora quanto sopra ottiene il percorso completo sulla mia macchina e immagino che sarebbe per la maggior parte delle persone nella maggior parte dei casi. Posso anche immaginare che potrebbe fallire. È solo un'euristica approssimativa.
Questo potrebbe non riuscire per molte altre ragioni probabilmente, ma se sei su un sistema che consente al leader della sessione di rinunciare a tutti i descrittori al ctty e tuttavia rimane il sid allora come le specifiche lo consentono, allora sicuramente non sarà di aiuto. Detto questo, penso che questo possa ottenere una stima abbastanza buona nella maggior parte dei casi.
Naturalmente la più semplice cosa da fare se si dispone di eventuali descrittori collegati al CTTY è solo ...
tty <&2
...o simili.
ps
soluzione copra la maggior parte dei sistemi (ewho
non aiuta più dips
), possibilmente con un po 'più di codice per gestire l'identificatore da solo (come "04"). Mi chiedevo se esistesse una soluzione ancora più portatile.