原始版本
一种方法是获取当前Shell会话的父进程,然后从那里获取终端名称。
获取当前shell进程的父级。bash变量$$
是您当前shell的PID,因此我们可以将其作为对ps
(-p $$
)的查询,并要求它tp打印父进程的PID(-o ppid=
,其后缀=
是避免打印列标题):
$ ps -p $$ -o ppid=
544
因此,我的外壳程序父级的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
与其他用户联系后运行外壳程序时,或者当您的终端被别名为某种东西以及其他各种情况时,它将阻塞。由于我们显然在这里使用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"
}
这适用于我测试过的所有情况。