Come posso ottenere il nome del terminale corrente dalla riga di comando?


25

Esiste la possibilità di ottenere il tipo di terminale con un comando?

Se sto usando gnome-terminal, l'output dovrebbe essere gnome-terminalo qualcosa di simile. Sarebbe anche bello avere la versione del terminale.

Aggiornare

ps -aux | grep `ps -p $$ -o ppid=` 

produrrà qualcosa del genere:

user     4239  0.0  0.7 292708 15744 pts/8    Sl   11:39   0:02 xfce4-terminal
user     4800  0.0  0.0   6176   820 pts/0    S+   12:23   0:00 grep --color=auto  4239

Funzionerà anche con xterm, ma come posso ottenere solo il nome ( xfce4-terminalin questo caso)?


Ho appena aggiornato la mia risposta con un approccio diverso e migliore. Se hai tempo, dai un'occhiata e fammi sapere se funziona anche per te.
terdon,

Grazie ma primo problema con rxvt -> window 31457282 has no pid associated with it(testato su Lubuntu)
TuKsn

Oh? Accidenti, è strano. Ho provato con Cannella.
terdon,

Risposte:


29

Versione originale

Un modo per farlo è ottenere il processo genitore della tua sessione di shell corrente e da lì il nome del terminale.

  1. Ottieni il genitore dell'attuale processo di shell. La variabile bash $$è il PID della shell corrente, quindi possiamo fornirlo come query a ps( -p $$) e chiedergli di stampare il PID del processo parent ( -o ppid=il trailing =è quello di evitare la stampa delle intestazioni di colonna):

    $ ps -p $$ -o ppid=
    544
    

    Quindi, il PID del genitore della mia shell è 544.

  2. Ottieni il processo associato a quel PID e stampa la sua riga di comando

    $ ps -p 544 o args=
    /usr/bin/python /usr/bin/terminator
    

    L'output sopra dipenderà dall'emulatore di terminale che stai usando, che sto usando terminator.

  3. Combina tutto in un unico comando

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Usalo per ottenere la versione

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Aggiungi una piccola funzione alla tua ~/.bashrcche restituisca il nome e la versione dell'emulatore di terminale che stai utilizzando (funziona per i più comuni emulatori di terminale):

    which_term(){
        term=$(ps -p $(ps -p $$ -o ppid=) -o args=);
        found=0;
        case $term in
            *gnome-terminal*)
                found=1
                echo "gnome-terminal " $(dpkg -l gnome-terminal | awk '/^ii/{print $3}')
                ;;
            *lxterminal*)
                found=1
                echo "lxterminal " $(dpkg -l lxterminal | awk '/^ii/{print $3}')
                ;;
            rxvt*)
                found=1
                echo "rxvt " $(dpkg -l rxvt | awk '/^ii/{print $3}')
                ;;
            ## Try and guess for any others
            *)
                for v in '-version' '--version' '-V' '-v'
                do
                    $term "$v" &>/dev/null && eval $term $v && found=1 && break
                done
                ;;
        esac
        ## If none of the version arguments worked, try and get the 
        ## package version
        [ $found -eq 0 ] && echo "$term " $(dpkg -l $term | awk '/^ii/{print $3}')    
    }

    Ora puoi ottenere il nome del terminale e passare anche qualsiasi opzione che ti piace (come --version.

Alcuni esempi usando terminali diversi:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, questo non ha nessuno dei flag o -V, quindi non viene stampata alcuna informazione sulla versione.-version--version

    $  which_term
    rxvt  1:2.7.10-5
    
  4. gnome-terminal.

    $ which_term
    gnome-terminal  3.10.1-1
    
  5. konsole

    $ which_term
    Qt: 4.8.6
    KDE Development Platform: 4.11.3
    Konsole: 2.11.3
    
  6. lxterminal

    $ which_term
    lxterminal  0.1.11-4
    
  7. xfce4-terminal

    $ which_term
    xfce4-terminal 0.6.2 (Xfce 4.10)
    
    Copyright (c) 2003-2012
        The Xfce development team. All rights reserved.
    
    Written by Benedikt Meurer <benny@xfce.org>
    and Nick Schermer <nick@xfce.org>.
    
    Please report bugs to <http://bugzilla.xfce.org/>.
    

Nuovo e migliorato

L'approccio di cui sopra non è poi così affidabile. Si strozzerà quando esegui la shell dopo aver eseguito l' suinstallazione su un altro utente o quando il tuo terminale è aliasato su qualcosa e vari altri casi. Dato che ovviamente stiamo lavorando con i programmi X qui, un modo migliore potrebbe essere quello di usare qualcosa come xdotool(installabile con sudo apt-get install xdotool) per ottenere le informazioni:

perl -lpe 's/\0/ /g' /proc/$(xdotool getwindowpid $(xdotool getactivewindow))/cmdline

Quanto sopra stamperà la riga di comando utilizzata per avviare la finestra attualmente attiva. Poiché il tuo terminale sarà, presumibilmente, attivo, questo è il comando che mostrerà. Ciò significa che per la maggior parte degli emulatori di terminale, puoi tranquillamente supporre che il primo campo restituito sia il nome del terminale:

$ which_term 
lxterminal 

Ciò significa che ottenere la versione è banale. Per esempio

$ dpkg -l $(which_term) | awk '/^ii/{print $3}'
0.1.11-4

Non così per gnome-terminal:

$ which_term 
/usr/lib/gnome-terminal/gnome-terminal-server 

oppure terminator:

$ which_term
/usr/bin/python /usr/bin/terminator 

Quindi, possiamo renderlo un po 'più complesso (ci sono alcuni bashismi qui, questo non è portatile):

which_term(){
    term=$(perl -lpe 's/\0/ /g' \
           /proc/$(xdotool getwindowpid $(xdotool getactivewindow))/cmdline)

    ## Enable extended globbing patterns
    shopt -s extglob
    case $term in
        ## If this terminal is a python or perl program,
        ## then the emulator's name is likely the second 
        ## part of it
        */python*|*/perl*    )
         term=$(basename "$(readlink -f $(echo "$term" | cut -d ' ' -f 2))")
         version=$(dpkg -l "$term" | awk '/^ii/{print $3}')
         ;;
        ## The special case of gnome-terminal
        *gnome-terminal-server* )
          term="gnome-terminal"
        ;;
        ## For other cases, just take the 1st
        ## field of $term
        * )
          term=${term/% */}
        ;;
     esac
     version=$(dpkg -l "$term" | awk '/^ii/{print $3}')
     echo "$term  $version"
}

Questo funziona per tutti i casi su cui ho provato.


@ Xubu-Tur hmm, ho provato solo avviando manualmente ciascun terminale da un altro terminale e ha funzionato bene. Immagino che i menu del tuo ambiente desktop abbiano un percorso diverso o in qualche modo differiscano nel modo in cui avviano i terminali. Potrei essere in grado di darti qualcosa di meglio se mi dici esattamente come li hai lanciati e quale errore hai avuto. Se è stato avviato da un menu, controllare quale comando esegue la voce di menu.
terdon,

@ Xubu-Tur non aggiunge uno screenshot. Basta incollare il messaggio di errore nella tua domanda. Lo stesso vale per qualsiasi comando venga avviato l'elemento di menu. Non aspettarti che lo copi manualmente da una foto!
terdon,

2
Puoi semplicemente usare $PPIDper ottenere il PID del processo genitore.
nyuszika7h

@ nyuszika7h sì, puoi e +1 per quello, ma preferirei di no. Ho appena controllato e non è disponibile in ksho tcsh. È una buona idea per la famiglia Bash, dato che è molto più semplice del mio approccio.
Terdon,

È sicuramente disponibile in ksh93e mksh.
nyuszika7h,

8

Prova questo,

ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $11}'

O

ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $NF}'

Il primo non riesce a rxvted terminatore il secondo fallisce su uxterme gnome-terminal(la stampa /usr/lib/gnome-terminal/gnome-terminal-server). Falliranno tutti (come il mio) se stai usando una sessione su.
terdon,

7
basename "$(cat "/proc/$PPID/comm")"

$PPIDè il PID del processo genitore della shell. commsignifica comando . Può essere o meno un percorso completo, quindi usiamo basenameper eliminare il percorso se necessario.

Avvertenze

Questi probabilmente si applicano anche ad almeno alcune delle altre risposte.

  • commè tecnicamente argv[0], che può effettivamente essere una stringa arbitraria. Ma in generale, dovresti essere in grado di fare affidamento su di esso per questo caso particolare.

  • Questo non funzionerà come previsto se si collega su SSH o l'uso tmux, screeno qualcosa di simile.


Questo è un bel +1, ma sul terminale di terminazione ottengo solo termincome output.
TuKsn,

Non so perché, probabilmente è colpa di Terminator.
nyuszika7h

È perché penso che sia eseguito come uno script Python. È veramente noioso.
Terdon,

Si noti che $PPIDnon è standard in tutte le shell. ad esempio in tcshottengo:PPID: Undefined variable.
arielf

2

Puoi provare il seguente comando:

$ dpkg-query -W $COLORTERM
gnome-terminal  3.6.2-0ubuntu1

Aggiornamento (grazie a OP e Avinash Raj):

$ dpkg-query -W $(ps -aux | grep "`ps -p $$ -o ppid=`" | awk 'NR==1{print $11}' | xargs basename)
rxvt    1:2.7.10-5

Penso che lo voglia sapere per la sessione terminale attiva :) Quindi se sta usando "stucco" in quel momento ...
Rinzwind

No, non per "stucco" ma per quanto riguarda xterm, con questo comando ottengo anche gnome-terminal 3.6.2-0ubuntu1lin xterm?
TuKsn,

2
Questo non stampa il terminale che stai utilizzando al momento. Stampa tutto ciò che è stato impostato come $ COLORTERM predefinito, che non ha nulla a che fare con quello che stai usando in quel momento.
terdon,

L'aggiornamento funziona bene anche con xterm e mostra la versione e il nome.
TuKsn,

Tutto il merito va a @Avinash e tu per il comando giusto. Ho appena aggiunto la versione.
Sylvain Pineau,

2

Un'altra possibilità (non perfetta) è:

xprop -id $WINDOWID WM_CLASS | cut -d" " -f3 | sed 's/^.\(.*\)..$/\1/'

Ma questo non funziona con lxterminal perché la variabile di ambiente è $WINDOWIDvuota ...

Terminator mostra il nome "emulatore x-terminal".


0

Il terminale corrente può anche essere rilevato tramite una sequenza di escape: The Device Attributes (Secondary DA)

Ad esempio in bash:

read -s -dc -p $'\E[>c' da;da=${da##$'\E'[>};echo "${da//;/ }"

Questo restituisce solo una sorta di id - e purtroppo non conosco un elenco ufficiale che li traduca con i nomi reali.


Per un'implementazione reale, che traduce alcuni ID noti in nomi di terminali, vedere questo script bash di esempio: https://github.com/mintty/utils/blob/master/terminal

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.