0

我一直在尝试仅显示用作名称的终端类型。例如,如果我使用的是 konsole,它将显示 konsole。到目前为止,我一直在使用这个命令。

pstree -A -s $$

输出这个。

systemd---konsole---bash---pstree

我有以下可以从该行中提取 konsole

pstree -A -s $$ | sed 's/systemd---//g;s/---.*//g' | head -1

并且正确输出konsole。但是有些人仅从 pstree 命令的输出可以看起来像这样。

systemd---kdeinit4---terminator---bash---pstree

或这个

systemd---kdeinit4---lxterminal---bash---pstree

然后当我添加 sed 命令时,它会提取 kdeinit4 而不是终止符。我可以想到几个场景来提取终端的类型,但没有一个场景不包含条件语句来检查特定类型的终端。我遇到的问题是我无法准确预测终端名称前面或后面可能有多少非或非相关事物或它们将是什么,我也无法准确预测终端名称将是什么。有没有人对此有任何想法?

4

4 回答 4

1

你可以使用

ps -p "$PPID" -o comm=

或者

ps -p "$PPID" -o fname=

如果您的外壳没有设置 PPID 变量,您可以使用

ps -p "$(ps -p "$$" -o ppid= | sed 's|\s\+||')" -o fname=

另一种理论是,当前 shell 的父进程与 shell 不属于同一个 tty,实际上可能是产生虚拟终端的那个,所以我们也可以这样找到它:

#!/bin/bash

shopt -s extglob

SHELLTTY=$(exec ps -p "$$" -o tty=)
P=$$

while read P < <(exec ps -p "$P" -o ppid=) && [[ $P == +([[:digit:]]) ]]; do
    if read T < <(exec ps -p "$P" -o tty=) && [[ $T != "$SHELLTTY" ]]; then
        ps -p "$P" -o comm=
        break
    fi
done
于 2013-08-26T21:39:58.873 回答
0

我不知道如何在您的系统上隔离终端名称,但作为解析练习,并假设终端直接运行您的 bash,您可以通过以下方式管道 pstree 输出:

 awk -F"---bash---" ' NF == 2 { count = split( $1, arr, "---" ); print arr [count]; }'

这将在您的示例中找到“---bash---”之前的单词

konsole
terminator
lxterminal

如果您想要不同的外壳类型,您可以扩展字段分隔符以包含它们,例如:

awk -F"---(bash|csh)---" ' NF == 2 { count = split( $1, arr, "---" ); print arr[count]; }'

考虑一条假想线,例如:

systemd---imaginary---monkey---csh---pstree

awk 会找到“monkey”作为终端名称以及您的测试集中的任何内容。

于 2013-08-26T21:59:42.887 回答
0
curTerm=$(update-alternatives --query x-terminal-emulator | grep '^Best:')
curTerm=${curTerm##*/}

printf "%s\n" "$curTerm"

结果是

terminator

当然也可以不一样。
现在您可以$curTerm在 sed 命令中使用变量。

但我不确定这是否能与符号链接一起正常工作。

于 2013-08-26T21:39:04.840 回答
0

这里没有保证,但我认为这在 linux 上大部分时间都可以工作:

ps -ocomm= $(lsof -tl /proc/$$/fd/0 | grep -Fxf <(lsof -t /dev/ptmx))

一些解释可能是有序的,但请参阅man psman lsof(尤其是)man pts以获取信息。

/dev/ptmx是一个伪 tty 大师(在现代 linux 系统和其他一些 unix(-like) 系统上)。如果程序是终端仿真器、telnet/ssh 守护程序或其他需要强制终端的程序(screen例如 ),则程序将打开其中之一。模拟器将它想要“键入”的内容写入伪 tty 主机,并从伪 tty 从机读取结果。

/proc/$$/fd/0是进程的标准输入$$(即执行命令的shell)。如果 stdin 没有被重定向,这将是一个符号链接到一些从属伪对象 /dev/pts/#。那是 /dev/ptmx 设备的另一端,因此上面列出的所有/dev/ptmx打开的程序也会打开一些/dev/pts/#从属设备。(您可能认为您可以使用/dev/stdinor/dev/fd/0代替/proc/$$/fd/0,但它们会自行打开lsof,因此将是它的标准输入;由于lsof实现方式,这将不起作用。)使其遵循符号链接的-l选项,lsof所以这将导致它显示与当前 shell 具有相同 pts 打开的进程。

使其产生“简洁”输出的-t选项,仅由 pid 组成,每行一个。使其匹配字符串而不是正则表达式并强制全行匹配lsof-Fx选项;grep-f FILE选项使其接受要匹配的字符串FILE(在这种情况下是进程替换),每行一个。

最后,ps -ocomm=打印出对应于 pid 的“命令”(默认为 8 个字符)。

简而言之,该命令查找具有主伪 tty 的终端仿真器和其他主类似程序的列表,以及使用伪 tty 从属的进程列表;找到两者之间的交集,然后查找命令名称以获取任何结果。

于 2013-08-26T23:52:05.337 回答