
Я использовал pstree
для поиска имени родительского эмулятора запущенного скрипта оболочки что-то похожее на следующее:
pstree -s $PPID | awk -F '---' '{print $6}'
Это работает в моей текущей системе. Я тестировал в mate-terminal
и xterm
не уверен, будет ли это работать на других системах/платформах Linux и других терминалах. Есть ли лучший/более аккуратный (более портативный) способ добиться этого?
решение1
ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$$")))")))"
Может дать вам хорошие результаты. Он дает имя процесса, который является родителем лидера сеанса. Для процессов, запущенных в эмуляторе терминала, это, как правило, процесс, запускающий этот эмулятор терминала (если только не используются такие вещи, как screen
, expect
, ... (хотя обратите внимание, что иtmux
screen
tmux
являютсяэмуляторы терминала), или новые сеансы начинаются явно с помощью setsid
, start-stop-daemon
...)
Или разбить его на отдельные шаги с использованием переменных (что также может помочь сделать сценарий более понятным):
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")
Удаление пробелов вокруг чисел здесь выполняется с помощью $((...))
арифметического расширения. Вы также можете сделать это с помощью оператора split+glob (предполагая немодифицированный $IFS
) или, как предложил @ack в комментариях, с помощью xargs
:
ps -o sid= -p "$$" |
xargs ps -o ppid= -p |
xargs ps -o comm= -p
Вы также можете попробовать парсить, wtmp
где эмуляторы терминала обычно регистрируют запись с их pid, связанным с псевдотерминальным устройством. Это работает для меня в системе Debian, при условии, что expect/screen/tmux... не задействованы:
ps -o comm= -p "$(
dump-utmp -r /var/log/wtmp |
awk -v tty="$(ps -o tty= -p "$$")" -F ' *\\| *' '
$2 == tty {print $5;exit}')"
(используется dump-utmp
из GNU acct
).
решение2
Чтобы узнать имя эмулятора терминала, используемого текущей оболочкой, вы можете попросить систему X Window выдать вам имя окна, в котором в данный момент отображается оболочка:
$ xwininfo -id $WINDOWID | awk '/^xwin/ { print $NF }'
Это возвращает "xterm"
мне строку в XTerm, и "urxvt"
когда я запускаю в Rxvt-unicode. Результат, вероятно, будет другим, если у вас есть привычка менять заголовок окна, потому что это то, что возвращается вам здесь, я думаю.
решение3
Опираясь наСтефан-Шазелярешение заставить его работать под tmux (т.е. вернуть эмулятор терминала, который клиент tmux использует для отображения), мне кажется, это работает:
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