8

И не говорите « $TERM » - это всегда xterm .

Как bash скрипт может сказать, в каком терминале он работает, в частности, это iTerm, Terminal.app или на самом деле xterm?

Я спрашиваю, потому что reset не работает из коробки на Terminal.app и iTerm2. Однако iTerm2 распознает управляющую последовательность для сброса терминала (\x1b]50;ClearScrollback\x07), и, если бы я мог его обнаружить, я мог бы переопределить reset с помощью псевдонима, который делает правильные вещи. На самом деле, Terminal.app не хватает последовательности сброса, и люди прибегают к нелепым хакерским действиям, чтобы взломать это.

Моя конечная цель здесь - выполнить reset одинаково, работаю ли я на OS X или Linux, работаю локально или удаленно через SSH. (Я не хочу пытаться вспомнить, какие из них полезны, и полезно выполнить reset && command-that-outputs-a-bunch и выполнить начальную работу.) Terminal.app и iTerm вносят рывок в этот план, неправильно осуществляя reset .

Это означает, что просто переопределить reset не совсем так: если я на машине с Linux, нужно знать, использую ли я gnome-terminal или iTerm, чтобы отправить правильную escape-последовательность.

Есть ли способ (даже если мне нужен ioctl) спросить терминал, что это на самом деле ?

¹Для этого вопроса сброс должен очистить экран, сбросить курсор и стереть буфер прокрутки.

3 ответа3

10

Используйте $TERM_PROGRAM .

iTerm устанавливает его в iTerm.app , а Terminal.app в Apple_Terminal .

1

$TERM имеет ничего общего с запущенным в данный момент эмулятором терминала, это всего лишь ваш терминал по умолчанию, и его можно установить на что угодно. Чтобы получить имя эмулятора терминала, который вы используете, вы можете использовать ps чтобы получить PID родительского процесса вашей текущей оболочки.

ПРИМЕЧАНИЕ: следующее не будет работать в OSX, но должно работать нормально в Linux

PID вашего текущего процесса оболочки $$ . Оттуда вы можете использовать ps чтобы показать дерево процессов, и распечатать PID родителя вашего текущего сеанса оболочки:

ps -axjf | awk -v pid=$$ '($2==pid){print $1}'

Затем вы можете передать этот PID в ps и попросить его напечатать имя команды:

ps -o comm=  $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')

Это будет усекать имя, вам должно хватить, чтобы понять его, но это может быть не очень хорошо для сценариев. Чтобы получить полное имя, вы можете попробовать

ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'

Вот что я получаю в своей системе, используя несколько разных терминалов:

  1. terminator

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/bin/x-terminal-emulator
    
  2. gnome-terminal

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/lib/gnome-terminal/gnome-terminal-server
    
  3. xterm

    $ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    xterm
    
0

Вот портативный способ получить имя или путь родительского процесса:

iTerm 2:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm

гном-терминал в Ubuntu:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal

Terminal.app:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
login

Обратите внимание, что если Terminal.app настроен на открытие новых оболочек с помощью оболочки входа по умолчанию, родительским процессом оболочки является login а не терминал.

Столбец comm - это полный путь к команде в OS X и имя команды, усеченное до 15 символов в реализации procps в Linux.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .