Làm thế nào tôi có thể nhận được tên của thiết bị đầu cuối hiện tại từ dòng lệnh?


25

Có khả năng để có được loại thiết bị đầu cuối với một lệnh?

Nếu tôi đang sử dụng gnome-terminal, đầu ra nên gnome-terminalhoặc một cái gì đó tương tự. Nó cũng sẽ được tốt đẹp để có được phiên bản của thiết bị đầu cuối.

Cập nhật

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

sẽ xuất ra một cái gì đó như thế này:

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

Điều này cũng sẽ hoạt động với xterm, nhưng làm thế nào để tôi chỉ nhận được tên ( xfce4-terminaltrong trường hợp này)?


Tôi chỉ cập nhật câu trả lời của tôi với một cách tiếp cận khác và tốt hơn. Nếu bạn có thời gian, hãy xem và cho tôi biết nếu nó cũng phù hợp với bạn.
terdon

Cảm ơn nhưng vấn đề đầu tiên với rxvt -> window 31457282 has no pid associated with it(đã thử nghiệm trên
Lubfox

Oh? Chết tiệt, thật lạ. Tôi đã thử nghiệm dưới quế.
terdon

Câu trả lời:


29

Phiên bản gốc

Một cách để làm điều này là lấy tiến trình cha của phiên shell hiện tại của bạn và từ đó tên của thiết bị đầu cuối.

  1. Lấy cha mẹ của quá trình shell hiện tại. Biến bash $$là PID của trình bao hiện tại của bạn, vì vậy chúng tôi có thể đưa ra đó như là một truy vấn cho ps( -p $$) và yêu cầu nó in ra PID của quy trình cha mẹ ( -o ppid=, theo dõi =là để tránh in các tiêu đề cột):

    $ ps -p $$ -o ppid=
    544
    

    Vì vậy, PID của cha mẹ tôi là 544.

  2. Nhận quy trình liên quan đến PID đó và in dòng lệnh của nó

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

    Đầu ra ở trên sẽ phụ thuộc vào trình giả lập thiết bị đầu cuối nào bạn đang sử dụng, tôi đang sử dụng terminator.

  3. Kết hợp mọi thứ trong một lệnh duy nhất

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Sử dụng để có được phiên bản

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Thêm một chức năng nhỏ để ~/.bashrctrả về tên và phiên bản của trình giả lập thiết bị đầu cuối bạn đang sử dụng (công cụ này hoạt động với hầu hết các trình giả lập thiết bị đầu cuối phổ biến):

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

    Bây giờ bạn có thể lấy tên của thiết bị đầu cuối và cũng có thể chuyển bất kỳ tùy chọn nào bạn muốn cho nó (chẳng hạn như --version.

Một số ví dụ sử dụng các thiết bị đầu cuối khác nhau:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, cái này không có -V, -versionhoặc --versioncờ nên không có thông tin phiên bản nào được in.

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

Mới và cải tiến

Cách tiếp cận trên không phải là đáng tin cậy mặc dù. Nó sẽ bị nghẹt khi bạn chạy shell sau khi suing cho người dùng khác hoặc khi thiết bị đầu cuối của bạn được đặt bí danh cho một cái gì đó và các trường hợp khác. Vì rõ ràng chúng tôi đang làm việc với các chương trình X ở đây, nên cách tốt hơn có thể là sử dụng một cái gì đó như xdotool(có thể cài đặt với sudo apt-get install xdotool) để lấy thông tin thay thế:

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

Ở trên sẽ in dòng lệnh được sử dụng để khởi chạy cửa sổ hiện đang hoạt động. Vì thiết bị đầu cuối của bạn, có lẽ sẽ hoạt động, đó là lệnh mà nó sẽ hiển thị. Điều này có nghĩa là đối với hầu hết các trình giả lập thiết bị đầu cuối, bạn có thể giả định rằng trường thứ 1 được trả về là tên thiết bị đầu cuối:

$ which_term 
lxterminal 

Điều này có nghĩa là nhận được phiên bản là tầm thường. Ví dụ

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

Không phải vậy gnome-terminal:

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

hoặc terminator:

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

Vì vậy, chúng ta có thể làm cho nó phức tạp hơn một chút (có một số bashism ở đây, cái này không phải là di động):

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

Điều này làm việc cho tất cả các trường hợp tôi đã thử nghiệm trên.


@ Xubu-Tur hmm, tôi chỉ thử bằng cách khởi chạy từng thiết bị đầu cuối từ một thiết bị đầu cuối khác và nó hoạt động tốt. Tôi đoán các menu môi trường máy tính để bàn của bạn có một đường dẫn khác hoặc bằng cách nào đó khác nhau về cách chúng khởi chạy các thiết bị đầu cuối. Tôi có thể cung cấp cho bạn một cái gì đó tốt hơn nếu bạn cho tôi biết chính xác cách bạn khởi chạy chúng và lỗi bạn gặp phải. Nếu bạn đã khởi chạy từ một menu, hãy kiểm tra lệnh nào mà mục menu sẽ chạy.
terdon

@ Xubu-Tur không thêm ảnh chụp màn hình. Chỉ cần dán thông báo lỗi vào câu hỏi của bạn. Tương tự cho bất cứ lệnh nào, mục menu sẽ khởi chạy. Đừng mong tôi tự sao chép nó từ một bức tranh!
terdon

2
Bạn chỉ có thể sử dụng $PPIDđể có được PID của quá trình cha.
nyuszika7h

@ nyuszika7h có bạn có thể và +1 cho điều đó nhưng tôi thì không. Tôi chỉ kiểm tra và nó không có sẵn trong kshhoặc tcsh. Đó là một ý tưởng rất tốt cho gia đình bash mặc dù nó đơn giản hơn nhiều so với cách tiếp cận của tôi.
terdon

Nó chắc chắn có sẵn trong ksh93mksh.
nyuszika7h

8

Thử đi,

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

HOẶC LÀ

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

Là người đầu tiên không thành công trên rxvtterminatorvà lần thứ hai không thành công trên uxtermgnome-terminal(nó in /usr/lib/gnome-terminal/gnome-terminal-server). Tất cả đều thất bại (như của tôi) nếu bạn đang sử dụng phiên su.
terdon

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

$PPIDlà PID của quá trình cha của shell. commnghĩa là mệnh lệnh . Nó có thể hoặc không thể là một đường dẫn đầy đủ, vì vậy chúng tôi sử dụng basenameđể tách đường dẫn nếu cần.

Hãy cẩn thận

Những điều này có thể áp dụng cho ít nhất một số câu trả lời khác quá.

  • commlà về mặt kỹ thuật argv[0], mà thực sự có thể là một chuỗi tùy ý. Nhưng nói chung, bạn sẽ có thể dựa vào nó cho trường hợp cụ thể này.

  • Điều này sẽ không làm việc như mong đợi nếu bạn kết nối thông qua SSH hoặc sử dụng tmux, screenhoặc một cái gì đó tương tự.


Đây là +1 rất đẹp, nhưng trên thiết bị đầu cuối terminator tôi chỉ nhận được termindưới dạng đầu ra.
TuKsn

Tôi không biết tại sao, đó có lẽ là lỗi của Terminator.
nyuszika7h

Đó là bởi vì nó chạy như một kịch bản python tôi nghĩ. Nó thực sự phiền phức.
terdon

Xin lưu ý rằng đó $PPIDkhông phải là tiêu chuẩn trong tất cả các vỏ. ví dụ: trong tcshtôi nhận được:PPID: Undefined variable.
thân

2

Bạn có thể thử lệnh sau:

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

Cập nhật (nhờ OP và 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

Tôi nghĩ rằng anh ấy muốn biết nó cho phiên thiết bị đầu cuối hoạt động :) Vì vậy, nếu anh ấy đang sử dụng "putty" tại thời điểm đó ...
Rinzwind

Không không quá "putty" nhưng những gì về xterm, với lệnh này tôi cũng nhận được gnome-terminal 3.6.2-0ubuntu1ltrong xterm?
TuKsn

2
Điều này không in thiết bị đầu cuối bạn đang sử dụng tại thời điểm này. Nó in bất cứ thứ gì đã được đặt là $ COLORTERM mặc định, không liên quan gì đến những gì bạn đang sử dụng tại thời điểm đó.
terdon

Bản cập nhật cũng hoạt động tốt với xterm và hiển thị phiên bản và tên.
TuKsn

Tất cả tín dụng được chuyển đến @Avinash và bạn cho lệnh đúng. Tôi vừa mới thêm phiên bản.
Sylvain Pineau

2

Một khả năng khác (không hoàn hảo) là:

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

Nhưng điều này không hoạt động với lxterminal vì có biến môi trường $WINDOWIDtrống ...

Terminator hiển thị tên "x-terminal-giả lập".


0

Thiết bị đầu cuối hiện tại cũng có thể được phát hiện thông qua chuỗi thoát: Thuộc tính thiết bị (DA phụ)

Ví dụ trong bash:

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

Điều này chỉ trả về một số loại id - và thật đáng buồn là tôi không biết một danh sách chính thức dịch chúng sang tên thực tế.


Để triển khai thực sự, dịch một số id đã biết sang tên thiết bị đầu cuối, hãy xem tập lệnh bash ví dụ này: https://github.com/mintty/utils/blob/master/terminal

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.