
Eu costumava pstree
encontrar o nome do emulador pai da execução do shell script usando algo semelhante ao seguinte:
pstree -s $PPID | awk -F '---' '{print $6}'
Isso funciona no meu sistema atual. Eu testei mate-terminal
e xterm
não tenho certeza se isso funcionará em outros sistemas/plataformas Linux e outros terminais. Existe uma maneira melhor/mais organizada (mais portátil) de conseguir isso?
Responder1
ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$$")))")))"
Pode lhe dar bons resultados. Fornece o nome do processo que é pai do líder da sessão. Para processos iniciados em um emulador de terminal, esse geralmente seria o processo que executa esse emulador de terminal (a menos que coisas como screen
, expect
, tmux
... estejam sendo usadas (embora observe que screen
etmux
sãoemuladores de terminal), ou novas sessões são iniciadas explicitamente com setsid
, start-stop-daemon
...)
Ou dividindo-o em etapas individuais usando variáveis (o que também pode ajudar a tornar o script mais autoexplicativo):
sid=$(ps -o sid= -p "$$")
sid_as_integer=$((sid)) # strips blanks if any
session_leader_parent=$(ps -o ppid= -p "$sid_as_integer")
session_leader_parent_as_integer=$((session_leader_parent))
emulator=$(ps -o comm= -p "$session_leader_parent_as_integer")
A remoção dos espaços em branco em torno dos números aqui é feita usando $((...))
expansão aritmética. Você também pode fazer isso usando o operador split+glob (assumindo um unmodified $IFS
) ou conforme sugerido por @ack nos comentários usando xargs
:
ps -o sid= -p "$$" |
xargs ps -o ppid= -p |
xargs ps -o comm= -p
Você também pode tentar analisar wtmp
onde os emuladores de terminal geralmente registram uma entrada com seu pid associado ao dispositivo pseudo-terminal. Isso funciona para mim em um sistema Debian, desde que expect/screen/tmux... não esteja envolvido:
ps -o comm= -p "$(
dump-utmp -r /var/log/wtmp |
awk -v tty="$(ps -o tty= -p "$$")" -F ' *\\| *' '
$2 == tty {print $5;exit}')"
(usando dump-utmp
do GNU acct
).
Responder2
Para encontrar o nome do emulador de terminal usado pelo shell atual, você pode pedir ao sistema X window para fornecer o nome da janela na qual o shell está visível no momento:
$ xwininfo -id $WINDOWID | awk '/^xwin/ { print $NF }'
"xterm"
Isso me devolve a string no XTerm e "urxvt"
quando executo no Rxvt-unicode. O resultado provavelmente será diferente se você tiver o hábito de alterar o título da janela, porque é isso que está sendo devolvido a você aqui, eu acho.
Responder3
Construindo emstephane-chazelassolução para fazê-lo funcionar no tmux (ou seja, retornar o emulador de terminal que o cliente tmux está usando para exibição), isso parece funcionar para mim:
TERMINAL_EMULATOR="$(ps --pid $(ps --pid $$ -o ppid=) -o comm=)"
if [[ "${TERMINAL_EMULATOR}" =~ tmux ]]; then
export TERMINAL_EMULATOR=$(ps --pid "$(($(ps --pid $(ps --pid $(tmux display-message -p "#{client_pid}") -o sid=) -o ppid=)))" -o comm=)
else
export TERMINAL_EMULATOR
fi