Answers:
此功能应完成以下工作:
container() {
pid=$$
while true; do
pid=$(ps -h -o ppid -p $pid 2>/dev/null)
case $(ps -h -o comm -p $pid 2>/dev/null) in
(gnome-terminal) echo "Running in gnome terminal";return;;
(xterm) echo "Running in xterm";return;;
(rxvt) echo "Running in rxvt";return;;
(python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
esac
[[ $(echo $pid) == 1 ]] && break
done
}
container
bash: [: too many arguments
。有bash v4.2.24,python v2.7.3(如果有帮助)。
尝试这个:
echo $TERM
这更具权威性,但可能会被您的程序弄乱。但是在我的机器上,它表示xterm
,在ttys上表示linux
,我认为它代表Linux Console。
$TERM
是一个变量,它指的是所使用的终端仿真器自行报告的规范,而不是实际的仿真器本身。例如,在我的系统上,即使我实际上正在运行lxterminal ,也会echo $TERM
返回xterm
。正在发生的是lxterminal自报告xterm合规性。lxterminal实际上并不完全符合xterm,因此必须提防。规格文件通常位于中/usr/share/terminfo
。
您可以通过重复父进程的名称来获得终端仿真器的名称。因此,它适用于每个终端仿真器。
在bash,zsh等中:
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
带鱼壳:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
在许多Linux系统echo $TERM
回xterm
看stazher后上方。
要使用实际的终端,请执行以下操作:
1:关闭当前正在运行的每个终端实例。
2:使用常规方法打开新终端。
3:输入命令如下:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4:返回应该是这样的:
lxterminal --geometry=135x20
这是细分:
所以:ps
是“过程状态”
ps选项-o
是显示与指定的关键字的空格或逗号分隔列表关联的信息。听起来很复杂,但并非如此。(空格或逗号)分隔(关键字列表)指定。
因此,(关键字列表)'cmd='
仅是列表中的一个关键字。因此,仅要求显示命令即可打开终端。
ps选项-p
是“按进程ID”哇,这对于ps是非常好的选择。问题是,您必须将此进程ID传递给ps。那么,如何获取进程ID?我们解开表情 $(ps -o 'ppid=' -p $$)
在这里,我们必须开始更深入地思考。我希望我发明了这种bash一线纸,但我没有。我想我从https://wiki.archlinux.org/某个地方偷了它,我再也找不到了。那些家伙很棒,但是很多时候我不了解他们说要做什么,除非经过大量研究。我们能做的是现在就了解它,因为我会解释。
所以我们知道$
bash中的扩展运算符。我喜欢“解开包装”。因此,$(foo -opt bar)
将打开或扩展“ foo -opt bar”。但是在bash中,单个圆括号会(...)
打开子外壳。
因此,$(foo -opt bar)
将“ foo -opt bar”扩展为在子shell中运行。很奇怪,很难理解。
好的,现在我们再次运行几乎相同的命令,ps -o 'ppid=' -p $$
但是这次ps(进程状态)向我们展示了他在子shell实例中可以看到的内容。
-o
关键字列表,和以前一样只有一个关键字,但这ppid=
直接要求父shell的进程ID !从WITHAU DAUGHTER SHELL!非常聪明,是吗?当我能理解这一点时,我感到非常兴奋!
-p
同样,“按进程ID”和bash中的$$
是进程ID。
如果您调用ps -o 'ppid=' -p $$
,或任何其他$$
直接从第一个shell 请求的命令,他可能会说pid = 1,或者是xWindow或您的桌面程序中的pid,或者您可能会得到shell的实际pid。如果您问了很多遍,您每次可能都会得到不同的答案!
但是,如果您召唤一个女儿并问她“谁是您的爸爸”,她会告诉您!非常聪明。我希望我能成为这样的天才发明这种方法。
使用pstree
和awk
是最简单的方法:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
的$$
(在atual处理)。该pstree
参数:
-s
:显示流程的父级-A
:以纯ASCII显示输出。该awk
工具扫描模式并使用-F
参数来拆分进程。
'{ print $2 }'
告诉awk
仅输出第二匹配模式(在这种情况下,为终端仿真器名称)。$2
吗?就我而言,awk
实际上是systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
不是我使用的终端。
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
您是正确的,我只回答标题问题,而不回答正文问题。所以,你和鲍勃的叔叔去了。
在上面显示的一个答案中,我不确定大小写切换的含义。不需要这种情况下的切换。我的〜/ .bashrc脚本实际上只是简单的一行,所有的echo命令只是为了好玩。如何解释...
启动时的任何术语都读取〜/ .bashrc,并执行他将在.bashrc中看到的任何命令。因此,无论调用哪个术语,他都将读取.bashrc并执行命令,因此.bashrc中唯一需要的结构将是修改或排除一个或另一个术语的行为。期望的行为是每个术语都执行相同的命令,因此不需要大小写切换。Terminal本人将告诉您他的名字,因此无需区分。
注意(1)我没有测试guake,但适用于jlliagre在第一个答案中提到的所有其他内容。
注意(2)由于Wiki的降价格式,因此无法如图所示进行剪切和粘贴。您必须删除每个反引号,包括删除下划线字符,并添加实际的反引号,在之前ps
或之后没有空格-p $$)
。
〜/ .bashrc的脚本
# show welcome message for actual terminal in use
echo "Welcome. You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."
这很有趣。我已将此添加到我自己的〜/ .bashrc中。
如果您使用的是ZSH,则有更好的(更快)解决方案,该解决方案仅使用ZSH内置函数并/proc/$pid/{stat,cmdline}
直接进行操作。
get-terminal-emulator() {
if [[ $TTY = "/dev/tty"* ]]; then
echo "linux-console"
return
fi
local pid=$$ name=''
while true; do
proc_stat=(${(@f)$(</proc/${pid}/stat)})
name=${proc_stat[2]//[()]/}
case "${name}" in
gnome-terminal|konsole|rxvt|xterm)
echo "${name}"; return ;;
python*)
local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
echo "guake"; return
fi
;;
esac
if test "$pid" = "1" -o "$pid" = ""; then
echo "unknown"
return
fi
pid=${proc_stat[4]}
done
}
container
在定义之后实际调用该函数。