ฉันจะรับชื่อของเทอร์มินัลปัจจุบันจากบรรทัดคำสั่งได้อย่างไร


25

มีความเป็นไปได้ที่จะรับชนิดของเทอร์มินัลด้วยคำสั่งหรือไม่?

ถ้าฉันกำลังใช้gnome-terminalเอาต์พุตควรเป็นgnome-terminalอะไรที่คล้ายกัน มันจะเป็นการดีถ้าได้รับเวอร์ชันของเทอร์มินัล

ปรับปรุง

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

จะเอาท์พุทแบบนี้:

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

สิ่งนี้จะใช้ได้กับ xterm ด้วย แต่ฉันจะได้รับเฉพาะชื่อได้อย่างไร ( xfce4-terminalในกรณีนี้)


ฉันเพิ่งปรับปรุงคำตอบของฉันด้วยวิธีที่แตกต่างและดีกว่า หากคุณมีเวลาลองดูและแจ้งให้เราทราบว่ามันเหมาะกับคุณหรือไม่
terdon

ขอบคุณ แต่ปัญหาแรกที่มี rxvt -> window 31457282 has no pid associated with it(การทดสอบเกี่ยวกับ Lubuntu)
TuKsn

โอ้? ประณามนั่นแปลก ฉันทดสอบภายใต้ชินนามอน
terdon

คำตอบ:


29

รุ่นเดิม

วิธีหนึ่งในการทำเช่นนี้คือการรับโพรเซสแม่ของเชลล์ปัจจุบันของคุณและจากนั้นชื่อของเทอร์มินัล

  1. รับพาเรนต์ของกระบวนการเชลล์ปัจจุบัน ตัวแปร bash $$คือ PID ของเชลล์ปัจจุบันของคุณดังนั้นเราสามารถให้มันเป็นเคียวรีเพื่อps( -p $$) และขอให้มันพิมพ์ tp PID ของกระบวนการหลัก ( -o ppid=การต่อท้าย=คือการหลีกเลี่ยงการพิมพ์ส่วนหัวคอลัมน์):

    $ ps -p $$ -o ppid=
    544
    

    ดังนั้น PID 544ของผู้ปกครองเปลือกของฉันคือ

  2. รับกระบวนการที่เกี่ยวข้องกับ PID นั้นและพิมพ์บรรทัดคำสั่ง

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

    การส่งออกดังกล่าวจะขึ้นอยู่กับสิ่งจำลอง terminal terminatorคุณกำลังใช้ผมใช้

  3. รวมทุกอย่างไว้ในคำสั่งเดียว

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. ใช้สิ่งนั้นเพื่อรับเวอร์ชัน

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. เพิ่มฟังก์ชั่นเล็ก ๆ น้อย ๆ ของคุณ~/.bashrcที่ส่งคืนชื่อและรุ่นของเทอร์มินัลอีมูเลเตอร์ที่คุณใช้ (ใช้งานได้กับเทอร์มินัลอีมูเลเตอร์ทั่วไป):

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

    ตอนนี้คุณจะได้รับชื่อของสถานีและยังผ่านตัวเลือกที่คุณต้องการใด ๆ กับมัน --version(เช่น

ตัวอย่างบางส่วนที่ใช้เทอร์มินัลต่างๆ:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvtหนึ่งนี้มีไม่มีของ-V, -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/>.
    

ใหม่และปรับปรุง

วิธีการข้างต้นไม่น่าเชื่อถือ มันจะทำให้หายใจไม่ออกเมื่อคุณเรียกใช้เชลล์ของคุณหลังจากsuไอเอ็นจีกับผู้ใช้รายอื่นหรือเมื่อเทอร์มินัลของคุณมีนามแฝงกับบางสิ่งและกรณีอื่น ๆ เนื่องจากเราเห็นได้ชัดว่าทำงานร่วมกับโปรแกรม X ที่นี่วิธีที่ดีกว่าอาจใช้บางสิ่งเช่นxdotool(ติดตั้งได้sudo apt-get install xdotool) เพื่อรับข้อมูลแทน:

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

ด้านบนจะพิมพ์บรรทัดคำสั่งที่ใช้เพื่อเปิดหน้าต่างที่ใช้งานในปัจจุบัน เนื่องจากเทอร์มินัลของคุณจะใช้งานได้อย่างแน่นอนนั่นคือคำสั่งที่จะแสดง ซึ่งหมายความว่าสำหรับเทอร์มินัลอีมูเลเตอร์ส่วนใหญ่คุณสามารถสันนิษฐานได้ว่าฟิลด์ที่ 1 ที่ส่งคืนคือชื่อเทอร์มินัล:

$ which_term 
lxterminal 

ซึ่งหมายความว่าการรับรุ่นนั้นเล็กน้อย ตัวอย่างเช่น

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

ไม่เหมาะสำหรับgnome-terminal:

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

หรือterminator:

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

ดังนั้นเราสามารถทำให้มันซับซ้อนขึ้นเล็กน้อย (มี bashisms บางอย่างที่นี่อันนี้ไม่ได้พกพา):

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

สิ่งนี้ใช้ได้กับทุกกรณีที่ฉันทดสอบ


@ Xubu-Tur อืมฉันพยายามเพียงเปิดใช้เทอร์มินัลแต่ละตัวจากเทอร์มินัลอื่นด้วยตนเองและทำงานได้ดี ฉันคาดเดาเมนูสภาพแวดล้อมเดสก์ท็อปของคุณมีเส้นทางที่แตกต่างกันหรืออย่างใดก็แตกต่างกันในวิธีที่พวกเขาเปิดตัวอาคาร ฉันอาจจะให้อะไรที่ดีกว่านี้แก่คุณถ้าคุณบอกฉันได้อย่างแม่นยำว่าคุณเปิดตัวพวกเขาอย่างไรและเกิดข้อผิดพลาดอะไรขึ้น หากคุณเรียกใช้จากเมนูให้ตรวจสอบสิ่งที่สั่งให้รายการเมนูทำงาน
terdon

@ Xubu-Tur ไม่ได้เพิ่มภาพหน้าจอ เพียงวางข้อความแสดงข้อผิดพลาดในคำถามของคุณ เช่นเดียวกับคำสั่งอะไรก็ตามที่รายการเมนูเปิดใช้งาน อย่าคาดหวังว่าฉันจะคัดลอกจากรูปภาพด้วยตนเอง!
terdon

2
คุณสามารถใช้$PPIDเพื่อรับ PID ของกระบวนการพาเรนต์
nyuszika7h

@ nyuszika7h ใช่คุณทำได้และ +1 สิ่งนั้น แต่ฉันไม่อยากทำ ฉันเพียงแค่การตรวจสอบและก็ไม่ได้มีอยู่ในหรือksh tcshเป็นความคิดที่ดีมากสำหรับครอบครัวทุบตีแม้ว่ามันจะง่ายกว่าแนวทางของฉันมาก
terdon

มันมีอยู่ในksh93และmkshแน่นอน
nyuszika7h

8

ลองนี้

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

หรือ

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

ล้มเหลวครั้งแรกrxvtและterminatorและครั้งที่สองล้มเหลวuxtermและgnome-terminal(มันพิมพ์/usr/lib/gnome-terminal/gnome-terminal-server) พวกเขาทั้งหมดจะล้มเหลว (เช่นเดียวกับฉัน) ถ้าคุณใช้เซสชัน su
terdon

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

$PPIDเป็น PID ของกระบวนการหลักของเชลล์ commหมายถึงคำสั่ง อาจเป็นหรือไม่เป็นเส้นทางแบบเต็มดังนั้นเราใช้basenameเพื่อตัดเส้นทางหากจำเป็น

คำเตือน

เหล่านี้อาจนำไปใช้กับคำตอบอื่น ๆ อย่างน้อย

  • commเป็นเทคนิคargv[0]ซึ่งสามารถเป็นสตริงได้เอง แต่โดยทั่วไปแล้วคุณควรจะสามารถไว้ใจมันได้ในกรณีนี้

  • นี้จะไม่ทำงานตามที่คาดไว้ถ้าคุณเชื่อมต่อผ่าน SSH หรือการใช้งานtmux, screenหรือสิ่งที่คล้ายกัน


นี่เป็น +1 ที่ดีมาก แต่บนเทอร์มินัลเทอร์มินัลฉันได้รับเฉพาะterminผลลัพธ์
TuKsn

ฉันไม่รู้ว่าทำไมมันอาจเป็นความผิดของ Terminator
nyuszika7h

เป็นเพราะมันทำงานเป็นสคริปต์หลามฉันคิดว่า มันน่ารำคาญจริงๆ
terdon

โปรดทราบว่า$PPIDมันไม่ได้เป็นมาตรฐานในทุกเชลล์ เช่นในtcshฉันได้รับ:PPID: Undefined variable.
arielf

2

คุณสามารถลองคำสั่งต่อไปนี้:

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

อัปเดต (ขอบคุณ OP และ 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

ฉันคิดว่าเขาต้องการที่จะรู้ว่ามันสำหรับเซสชันเทอร์มินัลที่ใช้งานอยู่ :) ดังนั้นถ้าเขาใช้ "ผงสำหรับอุดรู" ในเวลานั้น ...
Rinzwind

ไม่ไม่เกิน "สีโป๊ว" แต่อะไรเกี่ยวกับ xterm ด้วยคำสั่งนี้ฉันได้รับยังgnome-terminal 3.6.2-0ubuntu1lอยู่ใน xterm?
TuKsn

2
นี่ไม่ได้พิมพ์เครื่องที่คุณใช้ในขณะนี้ มันจะพิมพ์สิ่งที่ได้รับการตั้งค่าเริ่มต้น $ COLORTERM ซึ่งไม่เกี่ยวข้องกับสิ่งที่คุณใช้ในเวลานั้น
terdon

การอัปเดตทำงานได้ดีกับ xterm และแสดงรุ่นและชื่อ
TuKsn

เครดิตทั้งหมดจะไปที่ @Avinash และคุณจะได้รับคำสั่งที่ถูกต้อง ฉันเพิ่งเพิ่มรุ่น
Sylvain Pineau

2

ความเป็นไปได้อื่น ๆ (ไม่สมบูรณ์) คือ:

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

แต่สิ่งนี้ไม่สามารถใช้ได้กับ lxterminal เนื่องจากมีตัวแปรสภาพแวดล้อม$WINDOWIDว่างเปล่า ...

Terminator แสดงชื่อ "x-terminal-emulator"


0

เทอร์มินัลปัจจุบันยังสามารถตรวจจับได้ผ่านทางลำดับหนีภัย: อุปกรณ์คุณสมบัติ (Secondary DA)

ตัวอย่างเช่นใน bash:

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

สิ่งนี้จะคืนค่า ID บางประเภทเท่านั้น - และน่าเศร้าที่ฉันไม่รู้รายชื่ออย่างเป็นทางการที่แปลสิ่งเหล่านี้เป็นชื่อจริง


สำหรับการใช้งานจริงที่แปลรหัสที่รู้จักไปเป็นชื่อเทอร์มินัลให้ดูตัวอย่างนี้ bash script: https://github.com/mintty/utils/blob/master/terminal

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.