如何从命令行获取当前终端的名称?


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 2014年

哦?该死,那很奇怪。我在肉桂下测试。
terdon

Answers:


29

原始版本

一种方法是获取当前Shell会话的父进程,然后从那里获取终端名称。

  1. 获取当前shell进程的父级。bash变量$$是您当前shell的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
    

    以上输出将取决于您正在使用的终端仿真器,我正在使用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

上面将打印用于启动当前活动窗口的命令行。由于您的终端可能处于活动状态,因此它将显示该命令。这意味着对于大多数终端仿真器,您可以放心地假设返回的第一个字段是终端名称:

$ 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 2014年

2
您可以使用$PPID来获取父进程的PID。
nyuszika7h 2014年

@ nyuszika7h是的,您可以为此+1,但我宁愿不这样做。我刚刚检查过,但在ksh或中都不可用tcsh。对于bash家族来说,这是一个非常好的主意,因为它比我的方法要简单得多。
terdon

肯定在ksh93和中可用mksh
nyuszika7h 2014年

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

第一失败上rxvtterminator与第二失败上uxtermgnome-terminal(它打印/usr/lib/gnome-terminal/gnome-terminal-server)。如果您使用su会话,它们都会全部失败(就像我的一样)。
terdon 2014年

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

$PPID是外壳程序父进程的PID。comm命令。它可能是完整路径,也可能不是完整路径,因此我们basename在需要时使用剥离路径。

注意事项

这些可能也适用于至少其他一些答案。

  • comm从技术上讲是argv[0],实际上可以是任意字符串。但总的来说,对于这种特殊情况,您应该可以依靠它。

  • 如果您通过SSH进行连接或使用或类似方式tmux,则此操作将无法正常工作screen


这是一个非常不错的+1,但是在终结器终端上我只能termin作为输出。
TuKsn 2014年

我不知道为什么,这可能是终结者的错。
nyuszika7h 2014年

我认为这是因为它作为python脚本运行。真烦人。
terdon 2014年

请注意,这$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

我认为他想在活动的终端会话中了解它:)因此,如果他当时正在使用“ putty” ...
Rinzwind 2014年

没有超过“ putty”,但是xterm又gnome-terminal 3.6.2-0ubuntu1l如何呢?通过这个命令我也可以在xterm中得到?
TuKsn14年

2
这不会打印您当前正在使用的终端。它会打印设置为默认$ COLORTERM的任何内容,与您当时使用的内容无关。
terdon 2014年

该更新还可以与xterm一起很好地工作,并显示版本和名称。
TuKsn14年

所有的功劳归功于@Avinash,您将获得正确的命令。我刚刚添加了版本。
Sylvain Pineau 2014年

2

另一种(不完美的)可能性是:

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

但这不适用于lxterminal,因为环境变量为$WINDOWID空...

终结器显示名称“ x-terminal-emulator”。


0

也可以通过转义序列来检测当前端子:设备属性(辅助DA)

例如在bash中:

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

这仅返回某种形式的ID-遗憾的是,我不知道将这些ID转换为实际名称的正式列表。


对于将某些已知ID转换为终端名称的实际实现,请参见以下示例bash脚本:https : //github.com/mintty/utils/blob/master/terminal

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.