Bagaimana cara memeriksa emulator terminal mana yang sedang digunakan?


15

Saya memiliki gnome-terminal dan Guake diinstal. Saya ingin memberikan pesan startup yang berbeda untuk ditampilkan pada terminal emulator ini ketika mereka mulai. Kode apa yang harus saya tulis dalam .bashrc sehingga ini tercapai?

Jawaban:


10

Fungsi ini harus melakukan pekerjaan:

container() {
    pid=$$
    while true; do
        pid=$(ps -h -o ppid -p $pid 2>/dev/null)
        case $(ps -h -o comm -p $pid 2>/dev/null) in
        (gnome-terminal) echo "Running in gnome terminal";return;;
        (xterm) echo "Running in xterm";return;;
        (rxvt) echo "Running in rxvt";return;;
        (python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
        esac
        [[ $(echo $pid) == 1 ]] && break
    done
}
container

Jawaban bagus! Jangan lupa untuk benar-benar memanggil fungsi containersetelah definisi.
Rosch

Saya berharap ini menjadi jelas tetapi Anda benar, jawab diperbarui sesuai.
jlliagre

@ jlliagre saya mencoba kode. Ini bekerja dengan lancar di terminal gnome tetapi memiliki masalah pada Guake. Itu tidak memberikan output. Sebaliknya itu agak membeku seolah-olah menemui jalan buntu. Saya harus Ctrl + C untuk menggunakannya. Tidak benar-benar mengerti kode itu jadi tidak tahu di mana itu salah.
VedVals

Kode diperbaiki. Saya melewatkan guake dijalankan oleh python dan memiliki bug yang mencegah fungsi untuk keluar. Terima kasih untuk umpan baliknya.
jlliagre

Maaf kawan, masih belum berfungsi. Memberi kesalahan bash: [: too many arguments. Punya bash v4.2.24, python v2.7.3 jika itu membantu.
VedVals

10

Coba ini:

echo $TERM

Ini lebih otoritatif, tetapi dapat dikacaukan oleh program Anda. Namun pada saya, katanya xtermdan pada tyys mengatakan linux, yang saya pikir singkatan dari Linux Console


2
$TERMadalah variabel yang merujuk pada spesifikasi yang dilaporkan sendiri oleh terminal emulator yang Anda gunakan, bukan ke emulator itu sendiri. Misalnya, di sistem saya, echo $TERMkembali xtermmeskipun saya sebenarnya menjalankan lxterminal. Apa yang terjadi adalah laporan mandiri lxterminal kepatuhan xterm. lxterminal sebenarnya tidak sepenuhnya sesuai xterm, jadi Anda harus berhati-hati. File spec biasanya terletak di /usr/share/terminfo.
keras

7

Anda bisa mendapatkan nama terminal emulator, dengan menangkap nama proses orang tua. Karena itu ia bekerja dengan setiap emulator terminal.

Dalam bash, zsh, dll .:

basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

Dengan cangkang ikan:

basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

Namun perlu dicatat, bahwa ini akan menangkap argumen program ketika emulator terminal diluncurkan bersama mereka.
Robobenklein

Apakah ini berfungsi jika saya terhubung menggunakan SSH?
user3731622

@ user3731622 tidak akan! Anda harus meneruskannya dari klien.
Enrico

2

Pada banyak sistem linux echo $TERMkembali xtermlihat posting lebih keras di atas.

Untuk mendapatkan terminal aktual yang digunakan, lakukan ini:

1: Tutup setiap instance terminal yang sedang berjalan.

2: Buka terminal baru menggunakan metode biasa.

3: Masukkan perintah sebagai berikut:

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)

4: Kembali harus seperti ini:

lxterminal --geometry=135x20

Berikut ini rinciannya:

Jadi: psadalah "status proses"

Opsi ps -oadalah Menampilkan informasi yang terkait dengan spasi atau daftar kata kunci yang dipisahkan koma yang ditentukan. Kedengarannya rumit, tetapi sebenarnya tidak. (spasi atau koma) dipisahkan (daftar kata kunci) ditentukan.

Jadi, (daftar kata kunci) 'cmd='Hanya satu kata kunci dalam daftar. Jadi, hanya meminta untuk menampilkan perintah untuk membuka terminal.

opsi ps -padalah "dengan proses id" Wow ini adalah opsi yang sangat bagus untuk ps. Masalahnya adalah, Anda harus meneruskan id proses ini. Jadi, bagaimana cara mendapatkan proses id? Kami membuka ekspresi $(ps -o 'ppid=' -p $$)

Di sini kita harus mulai berpikir sedikit lebih dalam. Saya berharap saya menemukan bash one-liner ini, tetapi saya tidak melakukannya. Saya rasa saya mencurinya dari https://wiki.archlinux.org/ di suatu tempat, saya tidak dapat menemukannya lagi. Orang-orang itu luar biasa, tetapi sering kali saya tidak mengerti apa yang mereka katakan sampai setelah banyak belajar. Yang bisa kita lakukan adalah memahaminya sekarang, karena saya akan jelaskan.

jadi kami tahu $adalah operator ekspansi di bash. Saya suka berpikir "un-wrap". Jadi, $(foo -opt bar)akan membuka, atau memperluas, "foo -opt bar". Tetapi dalam bash, penjepit putaran tunggal (...)membuka subkulit.

Jadi, $(foo -opt bar)perluas "foo -opt bar" seperti dijalankan di shell putri . Sangat aneh dan sulit dimengerti.

OK, jadi sekarang kita menjalankan perintah yang hampir sama lagi, ps -o 'ppid=' -p $$tetapi kali ini ps, status proses, menunjukkan kepada kita apa yang bisa dia lihat dari dalam instance shell putri .

-odaftar kata kunci, hanya satu kata kunci seperti sebelumnya, tetapi ppid=ini meminta langsung untuk proses id shell induk !! Dari DALAM DALAM SHELL! Sangat pintar, ya? Saya sangat senang ketika saya bisa memahami ini!

-plagi, "dengan id proses" dan dalam bash $$adalah id proses.

Jika Anda menelepon ps -o 'ppid=' -p $$, atau perintah lain yang meminta $$langsung dari shell pertama, ia mungkin mengatakan pid = 1, atau pid dari xWindow, atau dari program desktop Anda, atau Anda mungkin mendapatkan pid shell yang sebenarnya. Jika Anda bertanya berkali-kali, Anda mungkin mendapatkan jawaban yang berbeda setiap kali!

Tapi, jika Anda memohon seorang anak perempuan dan tanyakan padanya "Siapa Ayahmu" dia akan memberi tahu Anda! Sangat pintar. Saya berharap saya bisa menjadi jenius untuk menciptakan metode ini.


OK jadi AU tidak akan mengizinkan kerusakan yang tepat dalam satu posting. Maaf, tidak mau bertarung dengan sistem blog dan membuat banyak posting. Mungkin Anda bisa mendapatkan ide.
keras

Jawaban Anda yang lain tampaknya merupakan komentar yang canggih dan informatif tentang jawaban ini daripada jawaban untuk pertanyaan ... Akan lebih baik jika Anda dapat menggabungkan dua jawaban Anda menjadi satu dan menghapus salah satu dari mereka, dan menambahkannya sehingga sepenuhnya menjawab pertanyaan. Gunakan ---- untuk menggambar garis di tengah? Ada tombol juga.
Zanna

Saya pikir saya telah menjawab pertanyaan OP dengan tepat, dan secara terperinci. Anda melompat pada saya sebelum saya sempat memahami sistem edit blog dan menyelesaikannya. Mengambil suara turun, saya sudah terbiasa.
keras

1
Saya tidak berpikir saya melompat pada Anda, saya hanya melakukan review ... terima kasih telah membuat posting Anda lebih lengkap
Zanna

Terima kasih atas tanggapan Anda. Saya minta maaf, mungkin saya melompat pada Anda. Saya sangat minta maaf.
keras

1

Menggunakan pstreedan awkadalah cara termudah:

pstree -sA $$ | awk -F "---" '{ print $2 }'

Menjelaskan

  1. Tampilkan pohon proses dengan pstreedari $$(proses atual).
  2. The pstreeargumen:

    • -s: menampilkan orang tua dari suatu proses
    • -A: menampilkan output dalam ASCII murni.
  3. The awkalat memindai pola dan -Fargumen yang digunakan untuk membagi proses.

  4. Akhirnya '{ print $2 }'disuruh awkhanya menampilkan pola kecocokan ke-2 (dalam hal ini, nama terminal emulator).

Anda yakin tentang itu $2? Dalam kasus saya, apa yang disalurkan ke awksebenarnya systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree...
Enrico Maria De Angelis

@EnricoMariaDeAngelis Ya. Terima kasih atas pengamatannya. Dalam kasus saya terminal emulator menginisialisasi langsung dalam layanan systemd. Saya memeriksa lagi kode dan mengeditnya dengan koreksi.
silvadev

Ini tidak berfungsi ketika saya menggunakan pintasan keyboard untuk meluncurkan emulator. Pada XFCE, saya mendapatkan xfsettingsdbukan terminal yang saya gunakan.
Michael Hoffmann

Bekerja lebih baik jika Anda memulai dari akhir:pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
lleaff

0

Anda benar, saya hanya membuat jawaban untuk pertanyaan utama, bukan pertanyaan dalam tubuh. Jadi di sini Anda pergi, dan Paman Yer Bob.

Saya tidak yakin apa itu saklar kasus, dalam satu jawaban yang ditunjukkan di atas. Sakelar kasus seperti itu tidak diperlukan. Skrip ~ / .bashrc saya sebenarnya hanya satu baris sederhana, semua perintah gema hanya untuk bersenang-senang. Bagaimana cara menjelaskan...

Istilah apa pun saat mulai membaca ~ / .bashrc, dan menjalankan perintah apa pun yang akan dilihatnya di .bashrc. Jadi, tidak peduli istilah apa yang dipanggil, ia akan membaca .bashrc dan menjalankan perintah, jadi hanya struktur yang diperlukan dalam .bashrc adalah untuk memodifikasi perilaku atau mengecualikan satu istilah atau yang lain. Perilaku yang diinginkan adalah untuk setiap istilah untuk mengeksekusi perintah yang sama, jadi case switch tidak diperlukan. Terminal sendiri akan memberi tahu Anda bagaimana ia dipanggil, sehingga tidak perlu dibedakan.

Catatan (1) Saya tidak menguji guake, tetapi bekerja untuk semua yang lain yang disebutkan dalam jawaban pertama oleh jlliagre.

Catatan (2) Karena memformat dalam penurunan harga untuk wiki, Anda tidak dapat memotong dan menempelkan seperti yang ditunjukkan. Anda harus menghapus setiap backtick , termasuk untuk menghapus karakter yang digarisbawahi, dan menambahkan backtick yang sebenarnya, tanpa spasi sebelum psatau setelah -p $$).

skrip untuk ~ / .bashrc

# show welcome message for actual terminal in use
echo "Welcome.  You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."

Ini sangat menyenangkan. Saya telah menambahkan ini ke ~ / .bashrc saya sendiri.


per Catatan (1), telah diuji pada Tilda, berfungsi dengan baik. Guake mirip dengan Tilda, tetapi ditulis dalam python, jadi masih belum tahu tentang Guake.
keras

0

jika Anda menggunakan bash, saya kira perintah ini akan membantu Anda:

which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))


0

Jika Anda menggunakan ZSH, ada solusi yang lebih baik (lebih cepat), yang hanya menggunakan ZSH bawaan dan memanipulasi /proc/$pid/{stat,cmdline}secara langsung.

get-terminal-emulator() {
    if [[ $TTY = "/dev/tty"* ]]; then
        echo "linux-console"
        return
    fi
    local pid=$$ name=''
    while true; do
        proc_stat=(${(@f)$(</proc/${pid}/stat)})
        name=${proc_stat[2]//[()]/}
        case "${name}" in
            gnome-terminal|konsole|rxvt|xterm)
                echo "${name}"; return ;;
            python*)
                local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
                if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
                    echo "guake"; return
                fi
                ;;
        esac
        if test "$pid" = "1" -o "$pid" = ""; then
            echo "unknown"
            return
        fi
        pid=${proc_stat[4]}       
    done
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.