Wie kann ich den Namen des aktuellen Terminals über die Befehlszeile abrufen?

25

Gibt es eine Möglichkeit, die Art des Terminals mit einem Befehl abzurufen?

Wenn ich verwende gnome-terminal, sollte die Ausgabe so gnome-terminaloder so ähnlich sein. Es wäre auch schön, die Version des Terminals zu bekommen.

Aktualisieren

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

wird so etwas ausgeben:

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

Dies funktioniert auch mit xterm, aber wie bekomme ich nur den Namen ( xfce4-terminalin diesem Fall)?

TuKsn
quelle
Ich habe gerade meine Antwort mit einem anderen und besseren Ansatz aktualisiert. Wenn Sie die Zeit haben, schauen Sie und lassen Sie mich wissen, ob es auch für Sie funktioniert.
Terdon
Danke aber erstes Problem mit rxvt -> window 31457282 has no pid associated with it(getestet auf Lubuntu)
TuKsn
Oh? Verdammt, das ist komisch. Ich habe unter Zimt getestet.
Terdon

Antworten:

29

Originalfassung

Eine Möglichkeit, dies zu tun, besteht darin, den übergeordneten Prozess Ihrer aktuellen Shell-Sitzung und von dort den Namen des Terminals abzurufen.

  1. Ruft das übergeordnete Element des aktuellen Shell-Prozesses ab. Die Bash-Variable $$ist die PID Ihrer aktuellen Shell, daher können wir diese als Abfrage an ps( -p $$) senden und sie bitten, die PID des übergeordneten Prozesses zu drucken ( -o ppid=das Nachstellen =dient dazu, das Drucken von Spaltenüberschriften zu vermeiden):

    $ ps -p $$ -o ppid=
    544
    

    Die PID des übergeordneten Elements meiner Shell lautet also 544.

  2. Rufen Sie den mit dieser PID verknüpften Prozess ab und drucken Sie seine Befehlszeile

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

    Die obige Ausgabe hängt davon ab, welchen Terminalemulator Sie verwenden terminator.

  3. Kombinieren Sie alles in einem einzigen Befehl

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Verwenden Sie das, um die Version zu erhalten

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Fügen Sie Ihrer eine kleine Funktion hinzu, die ~/.bashrcden Namen und die Version des von Ihnen verwendeten Terminalemulators zurückgibt (dies funktioniert für die meisten gängigen Terminalemulatoren):

    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}')    
    }

    Sie können nun den Namen des Terminals abrufen und ihm eine beliebige Option übergeben (z --version. B..

Einige Beispiele mit verschiedenen Terminals:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, dieses hat keine der -V, -versionoder --versionFlags, so dass keine Versionsinformationen gedruckt werden.

    $  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 <[email protected]>
    and Nick Schermer <[email protected]>.
    
    Please report bugs to <http://bugzilla.xfce.org/>.
    

Neu und verbessert

Der obige Ansatz ist jedoch nicht so vertrauenswürdig. Es wird ersticken, wenn Sie Ihre Shell ausführen, nachdem suSie sie einem anderen Benutzer übergeben haben, oder wenn Ihr Terminal auf etwas und verschiedene andere Fälle ausgerichtet ist. Da wir hier offensichtlich mit X-Programmen arbeiten, besteht eine bessere Möglichkeit darin, stattdessen etwas wie xdotool(installierbar mit sudo apt-get install xdotool) zu verwenden, um die Informationen abzurufen:

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

Oben wird die Befehlszeile gedruckt, die zum Starten des aktuell aktiven Fensters verwendet wird. Da Ihr Terminal vermutlich aktiv sein wird, wird dieser Befehl angezeigt. Dies bedeutet, dass Sie bei den meisten Terminalemulatoren davon ausgehen können, dass das erste zurückgegebene Feld der Terminalname ist:

$ which_term 
lxterminal 

Dies bedeutet, dass das Abrufen der Version trivial ist. Beispielsweise

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

Nicht so für gnome-terminal:

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

oder terminator:

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

Also können wir es etwas komplexer machen (es gibt hier einige Bashismen, diese sind nicht portabel):

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"
}

Dies funktioniert in allen Fällen, in denen ich getestet habe.

terdon
quelle
@ Xubu-Tur hmm, ich habe nur versucht, jedes Terminal von einem anderen Terminal manuell zu starten und es hat gut funktioniert. Ich vermute, Ihre Desktop-Umgebungsmenüs haben einen anderen Pfad oder unterscheiden sich irgendwie darin, wie sie die Terminals starten. Ich könnte Ihnen vielleicht etwas Besseres geben, wenn Sie mir genau sagen, wie Sie sie gestartet haben und welchen Fehler Sie haben. Wenn Sie von einem Menü aus gestartet haben, überprüfen Sie, welchen Befehl der Menüpunkt ausführt.
Terdon
@ Xubu-Tur keinen Screenshot hinzufügen. Fügen Sie einfach die Fehlermeldung in Ihre Frage ein. Gleich für jeden Befehl, den der Menüpunkt startet. Erwarten Sie nicht, dass ich es manuell von einem Bild kopiere!
Terdon
2
Sie können nur verwenden $PPID, um die PID des übergeordneten Prozesses abzurufen.
Nyuszika7h
@ nyuszika7h ja du kannst und +1 dafür aber ich möchte lieber nicht. Ich habe es gerade überprüft und es ist in kshoder nicht verfügbar tcsh. Es ist eine sehr gute Idee für die Bash-Familie, da es viel einfacher ist als mein Ansatz.
Terdon
Es ist definitiv verfügbar in ksh93und mksh.
Nyuszika7h
8

Versuche dies,

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

ODER

ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $NF}'
Avinash Raj
quelle
Der erste Fehler tritt auf rxvtund terminatorund der zweite Fehler tritt auf uxtermund gnome-terminal(es wird gedruckt /usr/lib/gnome-terminal/gnome-terminal-server). Sie werden alle scheitern (wie auch meine), wenn Sie eine su-Sitzung verwenden.
Terdon
7
basename "$(cat "/proc/$PPID/comm")"

$PPIDist die PID des übergeordneten Prozesses der Shell. commbedeutet Befehl . Es kann sich um einen vollständigen Pfad handeln oder auch nicht. basenameDaher wird der Pfad bei Bedarf entfernt.

Vorbehalte

Dies gilt wahrscheinlich auch für einige der anderen Antworten.

  • commist technisch argv[0], was eigentlich eine beliebige Zeichenfolge sein kann. Aber im Allgemeinen sollten Sie sich in diesem speziellen Fall darauf verlassen können.

  • Das wird nicht funktionieren wie erwartet , wenn Sie über SSH oder Verwendung verbinden tmux, screenoder etwas ähnliches.

nyuszika7h
quelle
Das ist sehr schön +1, aber auf dem Terminator-Terminal bekomme ich nur terminals Ausgang.
TuKsn
Ich weiß nicht warum, es ist wahrscheinlich Terminators Schuld.
nyuszika7h
Es ist, weil es als Python-Skript ausgeführt wird, denke ich. Es ist wirklich nervig.
Terdon
Bitte beachten Sie, dass dies $PPIDnicht bei allen Shells Standard ist. zB in tcshich bekomme:PPID: Undefined variable.
Arielf
2

Sie können den folgenden Befehl versuchen:

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

Update (dank OP und 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
Sylvain Pineau
quelle
Ich denke, er möchte es für die aktive Terminal-Sitzung wissen :) Also, wenn er zu diesem Zeitpunkt "Kitt" verwendet ...
Rinzwind
Nein, nicht über "Kitt", aber was ist mit xterm, mit diesem Befehl bekomme ich auch gnome-terminal 3.6.2-0ubuntu1lin xterm?
TuKsn
2
Das aktuell verwendete Terminal wird nicht gedruckt. Es wird gedruckt, was auch immer als Standardwert für $ COLORTERM festgelegt wurde. Dies hat nichts mit dem zu tun, was Sie gerade verwenden.
Terdon
Das Update funktioniert auch mit xterm und zeigt die Version und den Namen an.
TuKsn
Der gesamte Kredit geht an @Avinash und Sie für den richtigen Befehl. Ich habe gerade die Version hinzugefügt.
Sylvain Pineau
2

Eine andere (nicht perfekte) Möglichkeit ist:

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

Dies funktioniert aber mit lxterminal nicht, da die Umgebungsvariable $WINDOWIDleer ist ...

Der Terminator zeigt den Namen "x-terminal-emulator".

TuKsn
quelle
0

Das aktuelle Terminal kann auch über eine Escape-Sequenz erkannt werden: Die Geräteeigenschaften (Secondary DA)

Zum Beispiel in der Bash:

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

Dies gibt nur eine Art von ID zurück - und leider kenne ich keine offizielle Liste, die diese in die tatsächlichen Namen übersetzt.


Eine echte Implementierung, die einige bekannte IDs in Terminalnamen übersetzt, finden Sie in diesem Beispiel-Bash-Skript: https://github.com/mintty/utils/blob/master/terminal

TS
quelle