我一直在尝试显示仅用作名称的终端类型。例如,如果我使用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而不是终结符。我可以想到几个场景来提取终端类型,但没有一个不包含条件语句来检查特定类型的终端。我遇到的问题是我无法准确预测终端名称或其后面会有多少非或非相关事物,也无法准确预测终端名称。有没有人对解决方案有任何想法?
答案 0 :(得分:1)
您可以使用
ps -p "$PPID" -o comm=
或者
ps -p "$PPID" -o fname=
如果您的shell没有设置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
答案 1 :(得分:0)
curTerm=$(update-alternatives --query x-terminal-emulator | grep '^Best:')
curTerm=${curTerm##*/}
printf "%s\n" "$curTerm"
结果是
terminator
当然可能会有所不同
现在,您可以在sed命令中使用$curTerm
变量。
但我不确定这是否适用于符号链接。
答案 2 :(得分:0)
我不知道如何隔离系统上的终端名称,但作为解析练习,并假设终端直接运行bash,您可以通过以下方式管道输出:
awk -F"---bash---" ' NF == 2 { count = split( $1, arr, "---" ); print arr [count]; }'
这将找到“--- bash ---”之前的单词,在你的例子中是
konsole
terminator
lxterminal
如果您需要不同的shell类型,可以展开字段分隔符以包含它们:
awk -F"---(bash|csh)---" ' NF == 2 { count = split( $1, arr, "---" ); print arr[count]; }'
考虑如下的虚线:
systemd---imaginary---monkey---csh---pstree
awk会将“monkey”作为终端名称以及测试集中的任何内容。
答案 3 :(得分:0)
这里没有保证,但我认为这大部分时间都适用于linux:
ps -ocomm= $(lsof -tl /proc/$$/fd/0 | grep -Fxf <(lsof -t /dev/ptmx))
可能会有一些解释,但请参阅man ps
,man lsof
和(特别是)man pts
以获取相关信息。
/dev/ptmx
是一个伪tty主服务器(在现代Linux系统和其他一些unix(类似)系统上)。如果程序是终端模拟器,telnet / ssh守护程序或其他需要捕获终端的程序(例如screen
),程序将打开其中一个程序。模拟器向pseudo-tty master写入它想要“键入”的内容,并从伪tty slave中读取结果。
/proc/$$/fd/0
是进程$$
的标准输入(即执行命令的shell)。如果stdin没有被重定向,那么这将是一些slave伪节的符号链接,/ dev / pts /#。这是/ dev / ptmx设备的另一面,因此上面列出的/dev/ptmx
打开的所有程序也将打开一些/dev/pts/#
从属设备。 (您可能认为可以使用/dev/stdin
或/dev/fd/0
代替/proc/$$/fd/0
,但这些将由lsof
本身打开,因此将成为其标准输入;因为方式lsof
已实现,但不起作用。)-l
的{{1}}选项会使其遵循符号链接,这样会导致它显示具有相同pts打开的进程作为当前的shell。
lsof
的{{1}}选项会导致它产生“简洁”输出,仅包含pids,每行一个。 -t
的{{1}}选项使其匹配字符串,而不是正则表达式,并强制完整的行匹配; lsof
选项使它接受来自-Fx
的匹配字符串(在这种情况下是一个进程替换),每行一个。
最后,grep
打印出对应于pid的“命令”(默认情况下,切碎为8个字符)。
简而言之,该命令找到一个终端仿真器列表和其他具有master伪tty的主类似程序,以及一个使用伪tty slave的进程列表;找到两者之间的交集,然后查找命令名称以获得任何结果。