Bagaimana saya bisa mendapatkan nama terminal saat ini dari command-line?

25

Apakah ada kemungkinan untuk mendapatkan jenis terminal dengan perintah?

Jika saya menggunakan gnome-terminal, hasilnya harus gnome-terminalatau sesuatu yang serupa. Akan menyenangkan juga untuk mendapatkan versi terminal.

Memperbarui

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

akan menampilkan sesuatu seperti ini:

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

Ini juga akan bekerja dengan xterm, tetapi bagaimana saya hanya mendapatkan nama ( xfce4-terminaldalam hal ini)?

TuKsn
sumber
Saya baru saja memperbarui jawaban saya dengan pendekatan yang berbeda dan lebih baik. Jika Anda punya waktu, lihatlah dan beri tahu saya jika itu juga cocok untuk Anda.
terdon
Terima kasih tetapi masalah pertama dengan rxvt -> window 31457282 has no pid associated with it(diuji di Lubuntu)
TuKsn
Oh Sial, itu aneh. Saya diuji di bawah Cinnamon.
terdon

Jawaban:

29

Versi asli

Salah satu cara untuk melakukan ini adalah dengan mendapatkan proses induk dari sesi shell Anda saat ini dan dari sana nama terminal.

  1. Dapatkan orang tua dari proses shell saat ini. Variabel bash $$adalah PID dari shell Anda saat ini, sehingga kami dapat memberikannya sebagai permintaan untuk ps( -p $$) dan memintanya untuk mencetak PID dari proses induk ( -o ppid=, trailing =adalah untuk menghindari mencetak tajuk kolom):

    $ ps -p $$ -o ppid=
    544
    

    Jadi, PID dari induk shell saya adalah 544.

  2. Dapatkan proses yang terkait dengan PID itu dan cetak baris perintahnya

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

    Output di atas akan tergantung pada emulator terminal apa yang Anda gunakan, saya menggunakan terminator.

  3. Gabungkan semuanya dalam satu perintah

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Gunakan itu untuk mendapatkan versinya

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Tambahkan sedikit fungsi ke Anda ~/.bashrcyang mengembalikan nama dan versi emulator terminal yang Anda gunakan (ini berfungsi untuk sebagian besar emulator terminal umum):

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

    Anda sekarang bisa mendapatkan nama terminal dan juga memberikan opsi apa saja yang Anda suka (seperti --version.

Beberapa contoh menggunakan terminal berbeda:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, yang ini tidak memiliki -V, -versionatau --versionbendera sehingga tidak ada info versi yang dicetak.

    $  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/>.
    

Baru dan ditingkatkan

Pendekatan di atas tidak begitu dapat dipercaya. Ini akan tersedak ketika Anda menjalankan shell Anda setelah masuk suke pengguna lain atau ketika terminal Anda dialihkan ke sesuatu dan berbagai kasus lainnya. Karena kami jelas bekerja dengan program X di sini, cara yang lebih baik mungkin dengan menggunakan sesuatu seperti xdotool(dapat diinstal dengan sudo apt-get install xdotool) untuk mendapatkan informasi sebagai gantinya:

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

Di atas akan mencetak baris perintah yang digunakan untuk meluncurkan jendela yang sedang aktif. Karena terminal Anda, mungkin, akan aktif, itu adalah perintah yang akan ditampilkan. Ini berarti bahwa untuk sebagian besar emulator terminal, Anda dapat dengan aman mengasumsikan bahwa bidang pertama yang dikembalikan adalah nama terminal:

$ which_term 
lxterminal 

Ini berarti mendapatkan versi itu sepele. Sebagai contoh

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

Tidak demikian untuk gnome-terminal:

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

atau terminator:

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

Jadi, kita bisa membuatnya sedikit lebih rumit (ada beberapa bashisme di sini, yang ini tidak 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"
}

Ini berfungsi untuk semua kasus yang saya uji.

terdon
sumber
@ Xubu-Tur hmm, saya hanya mencoba dengan meluncurkan setiap terminal dari terminal lain secara manual dan bekerja dengan baik. Saya menduga menu lingkungan desktop Anda memiliki jalur yang berbeda atau entah bagaimana berbeda dalam cara mereka meluncurkan terminal. Saya mungkin bisa memberi Anda sesuatu yang lebih baik jika Anda memberi tahu saya dengan tepat bagaimana Anda meluncurkannya dan kesalahan apa yang Anda dapatkan. Jika Anda meluncurkan dari menu, periksa perintah apa yang dijalankan item menu.
terdon
@ Xubu-Tur tidak menambahkan tangkapan layar. Cukup tempel pesan kesalahan ke pertanyaan Anda. Sama untuk perintah apa pun yang item menu luncurkan. Jangan harap saya menyalinnya secara manual dari gambar!
terdon
2
Anda bisa menggunakan $PPIDuntuk mendapatkan PID dari proses induk.
nyuszika7h
@ nyuszika7h ya Anda bisa dan +1 untuk itu tetapi saya lebih suka tidak. Saya baru saja memeriksa dan tidak tersedia di kshatau tcsh. Itu adalah ide yang sangat bagus untuk keluarga bash karena itu jauh lebih sederhana daripada pendekatan saya.
terdon
Ini pasti tersedia di ksh93dan mksh.
nyuszika7h
8

Coba ini,

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

ATAU

ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $NF}'
Avinash Raj
sumber
Yang pertama gagal pada rxvtdan terminatordan yang kedua gagal pada uxtermdan gnome-terminal(mencetak /usr/lib/gnome-terminal/gnome-terminal-server). Mereka semua akan gagal (seperti milik saya) jika Anda menggunakan sesi su.
terdon
7
basename "$(cat "/proc/$PPID/comm")"

$PPIDadalah PID dari proses induk shell. commberarti perintah . Ini mungkin atau mungkin bukan jalan penuh, jadi kami gunakan basenameuntuk menghapus jalur jika perlu.

Peringatan

Ini mungkin berlaku untuk setidaknya beberapa jawaban lain juga.

  • commsecara teknis argv[0], yang sebenarnya bisa menjadi string sewenang-wenang. Tetapi secara umum, Anda harus dapat mengandalkannya untuk kasus khusus ini.

  • Ini tidak akan berfungsi seperti yang diharapkan jika Anda terhubung melalui SSH atau menggunakan tmux, screenatau yang serupa.

nyuszika7h
sumber
Ini +1 yang sangat bagus, tetapi pada terminal terminator saya hanya mendapatkan terminsebagai output.
TuKsn
Saya tidak tahu mengapa, itu mungkin kesalahan Terminator.
nyuszika7h
Itu karena itu dijalankan sebagai skrip python saya pikir. Benar-benar menjengkelkan.
terdon
Harap dicatat bahwa $PPIDini tidak standar di semua shell. misalnya di tcshsaya dapatkan:PPID: Undefined variable.
arielf
2

Anda dapat mencoba perintah berikut:

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

Perbarui (terima kasih kepada OP dan 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
sumber
Saya pikir dia ingin mengetahuinya untuk sesi terminal aktif :) Jadi jika dia menggunakan "dempul" pada waktu itu ...
Rinzwind
Tidak tidak lebih dari "dempul" tetapi bagaimana dengan xterm, dengan perintah ini saya juga mendapatkan gnome-terminal 3.6.2-0ubuntu1ldalam xterm?
TuKsn
2
Ini tidak mencetak terminal yang Anda gunakan saat ini. Mencetak apa pun yang telah ditetapkan sebagai default $ COLORTERM, yang tidak ada hubungannya dengan apa yang Anda gunakan saat itu.
terdon
Pembaruan berfungsi dengan baik dengan xterm dan memperlihatkan versi dan namanya.
TuKsn
Semua kredit diberikan ke @Avinash dan Anda untuk perintah yang benar. Saya baru saja menambahkan versi.
Sylvain Pineau
2

Kemungkinan lain (tidak sempurna) adalah:

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

Tapi ini tidak berfungsi dengan lxterminal karena ada variabel lingkungan $WINDOWIDkosong ...

Terminator menunjukkan nama "x-terminal-emulator".

TuKsn
sumber
0

Terminal saat ini juga dapat dideteksi melalui urutan keluar: Atribut Perangkat (DA Sekunder)

Misalnya dalam bash:

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

Ini hanya mengembalikan semacam id - dan sayangnya saya tidak tahu daftar resmi yang menerjemahkan ini ke nama sebenarnya.


Untuk implementasi nyata, yang menerjemahkan beberapa id yang dikenal menjadi nama terminal, lihat contoh bash script ini: https://github.com/mintty/utils/blob/master/terminal

TS
sumber