Получить имя эмулятора терминала внутри скрипта оболочки

Получить имя эмулятора терминала внутри скрипта оболочки

Я использовал 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, ... (хотя обратите внимание, что иtmuxscreentmux являютсяэмуляторы терминала), или новые сеансы начинаются явно с помощью 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

Связанный контент