问题描述
是否可以通过命令获取终端的类型?
如果我使用的是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
)?
最佳办法
原始版本
一种方法是获取当前Shell会话的父进程,然后从那里获取终端名称。
-
获取当前shell进程的父级。 bash变量
$$
是当前shell的PID,因此我们可以将其作为对ps
(-p $$
)的查询,并要求它tp打印父进程的PID(-o ppid=
,后跟的=
以避免打印列标题):$ ps -p $$ -o ppid= 544
因此,我的 shell 程序父级的PID为
544
。 -
获取与该PID关联的进程并打印其命令行
$ ps -p 544 o args= /usr/bin/python /usr/bin/terminator
以上输出将取决于您使用的终端仿真器,我正在使用
terminator
。 -
将所有内容合并到一个命令中
ps -p $(ps -p $$ -o ppid=) o args=
-
使用它来获取版本
$(ps -p $(ps -p $$ -o ppid=) o args=) --version terminator 0.97
-
在
~/.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
)。
使用不同终端的一些示例:
-
xterm
$ which_term XTerm(297)
-
terminator
$ which_term terminator 0.97
-
rxvt
,这个没有-V
,-version
或--version
标志,因此不会打印任何版本信息。$ which_term rxvt 1:2.7.10-5
-
gnome-terminal
。$ which_term gnome-terminal 3.10.1-1
-
konsole
$ which_term Qt: 4.8.6 KDE Development Platform: 4.11.3 Konsole: 2.11.3
-
lxterminal
$ which_term lxterminal 0.1.11-4
-
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
给另一个用户运行 shell 程序时,或者当您的终端被别名为其他情况时,它将阻塞。因为我们显然在这里使用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"
}
这适用于我测试过的所有情况。
次佳办法
尝试这个,
ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $11}'
要么
ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $NF}'
第三种办法
basename "$(cat "/proc/$PPID/comm")"
$PPID
是 shell 程序父进程的PID。 comm
表示命令。它可能不是完整路径,因此如果需要,我们使用basename
剥离路径。
Caveats
这些可能也适用于至少其他一些答案。
-
从技术上讲
comm
是argv[0]
,实际上可以是任意字符串。但总的来说,在这种情况下,您应该可以依靠它。 -
如果您通过SSH连接或使用
tmux
,screen
或类似方法,则此操作将无法正常工作。
第四种办法
您可以尝试以下命令:
$ 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
第五种办法
另一种(不完美的)可能性是:
xprop -id $WINDOWID WM_CLASS | cut -d" " -f3 | sed 's/^.\(.*\)..$/\1/'
但这不适用于lxterminal,因为环境变量$WINDOWID
为空…
终结器显示名称”x-terminal-emulator”。