스크립트에서 터미널을 식별하는 방법은 무엇입니까?


8

그리고 " $TERM" 라고 말하지 마십시오 – 항상 그렇습니다 xterm.

어떻게 할 수 bash스크립트는 xterm을 구체적으로의 사용하여 ITerm, Terminal.app 여부, 또는 실제로에서 실행중인 터미널 무엇을 말해?

resetTerminal.app 및 iTerm2의 상자에서 ¹ 작동하지 않기 때문에 묻습니다. 그러나 iTerm2는 터미널 재설정 ( \x1b]50;ClearScrollback\x07) 을 수행하기위한 이스케이프 시퀀스를 인식하고 감지 할 수 있다면 reset올바른 일을하는 별칭으로 재정의 할 수 있습니다 . AFAICT, Terminal.app에는 재설정 시퀀스가 ​​없으며 사람들은 그 말을 해킹하기 위해 말도 안되는 톰 해커에 의지합니다 .

여기서 최종 목표는 resetOS X 또는 Linux에서 작업하든 SSH를 통해 로컬 또는 원격으로 작업하든 동일하게 작동하는 것입니다. (어떤 것을 기억하려고 할 필요가 없으며, 수행하고 작업하는 것이 유용합니다 reset && command-that-outputs-a-bunch.) Terminal.app 및 iTerm은 reset올바르게 구현하지 않아이 계획에서 렌치를 던지고 있습니다.

이것은 단순히 재정의 reset가 그다지 쉽지 않다는 것을 의미합니다 . Linux 시스템에 있다면 gnome-terminal올바른 이스케이프 시퀀스를 보내려면 내가 사용 중인지 또는 iTerm 인지 알아야합니다 .

(I가 필요한 경우에도 방법이 있나요 ioctl이 무엇 터미널 물어) 정말 이다?

¹이 질문의 목적 상, 재설정은 화면을 지우고 커서를 재설정하고 스크롤 백 버퍼를 초기화해야합니다.


글쎄, 이것은 버그가 아닌 기능이므로 그렇게 말합니다. Terminal.app의 설정, 터미널 탭 을 열고 스크롤 백 라인을 0으로 설정 하면 어떻게됩니까 ? 현재 줄 위의 모든 텍스트 또는 화면 상단의 모든 텍스트를 비활성화합니까? 나는 그것이 당신이 요구 한 것과 정확히 일치하지는 않습니다.
nitro2k01

@ nitro2k01 : 그것이 무엇을 성취 할 지 잘 모르겠습니다. 내가 원하는 스크롤 백. 나는 reset손가락을 알고 있기 때문에 이제 그것을 지우고 싶을 때 바람직하게는을 사용할 수 있기를 원합니다 .
Thanatos

"재설정"문제와 관련하여 명확하게하기 위해 reset터미널 에뮬레이터의 스크롤 백 내용을 지우는 명령을 기대하고 있지만 스크롤 백은 터미널 에뮬레이터 관련 기능이 아니기 때문에 그렇게 할 수는 없습니다. 터미널의 일부. 그러나 터미널은 ED (Erase in Display) 이스케이프 시퀀스 확장을 지원하여 스크롤 백을 지 웁니다 ESC [ 3 J. 화면을 지우고 다음과 같이 사용할 수 있습니다.reset && printf '\e[3J’
Chris Page

여기에 내 대답을 참조하십시오 apple.stackexchange.com/a/113168/6883을 표시 확장의 삭제에 대한 자세한 내용은.
Chris Page

@ChrisPage : 터미널이 기발한 일이라는 것을 알고 있지만 자신을 xterm(통과 TERM=xterm) 으로 선언 하면 XTerm의 수퍼 세트를 에뮬레이트하여 재설정시 스크롤 백을 지우는 것으로 기대합니다. ( "blue"에 대한 이스케이프 시퀀스를 보낸 것처럼 파란색을 기대할 것입니다.) 물론 내 xterm은 나 Erase is backspace.에게 아무 것도 감사하지 않습니다. 그것은 단지 성가신 일입니다.
Thanatos

답변:


10

사용하십시오 $TERM_PROGRAM.

iTerm은로 설정 iTerm.app하고 Terminal.app 는로 설정합니다 Apple_Terminal.


Heh, OK, 이것은 내 핵보다 분명히 낫습니다, +1 :). 해킹은 두 터미널뿐만 아니라 모든 터미널 에뮬레이터에서도 작동합니다.
terdon

모든 터미널 에뮬레이터를 감지하는 단일 방법은 없습니다. xterm의 경우 예를 들어 $ XTERM_VERSION 변수를 확인할 수 있습니다. 아마도 OS X에서 가장 인기있는 세 가지 에뮬레이터가 무엇인지 알아볼 것입니다.
Chris Page

좋은 출발이기 때문에 이것을 받아들입니다. 불행히도이 변수는 SSH 세션 내에서 사용할 수 없으므로 쉽지 않습니다. 전달하기 위해 편집 할 수있는 구성이있는 것 같습니다.
Thanatos

1
@Thanatos은 sshd_configAcceptEnv아마. 이것은 (쉘이 터미널이 실행되는 호스트와 다른 호스트에서 실행 됨) 매우 중요한 정보이므로 실제로 질문의 일부가되어야합니다.
Daniel Beck

@DanielBeck : 그것은 엄격하지 않습니다; 로컬 및 원격으로 동일한 작업을 수행하고 싶습니다. 내가 원하는 것은 터미널에 "재설정"을 입력하면 OS X이든 Linux이든 로컬이든 원격이든 관계없이 터미널이 재설정됩니다. 나는 이것을 질문으로 편집했다.
Thanatos

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
    

OS X에서 작동하지 않습니다 :ps: illegal option -- f
Daniel Beck

@DanielBeck darn BSD 스타일, 감사합니다. 업데이트 된 버전으로 다시 시도해 주시겠습니까? -옵션을 OSX의에 따라 작동시키기 전에를 추가하십시오 man ps.
terdon

더 좋지만 여전히 작동하지 않습니다. 출력 형식이 다르고 (PID는 $2, PPID는이며 $3) 쉘의 상위 프로세스는 login다른 매개 변수를 사용하여 터미널 구성에 따라 다를 수 있습니다 . 그러나, 부모 프로세스이다 Terminal. --no-headers존재하지 않는 경우와 같은 것이 필요합니다 tail -n1. UI와 모든 프로세스가이 있기 때문에 그리고 인수를-psn_0_... , awk '{print $NF}'하나가 작동하지 않습니다.
Daniel Beck

@DanielBeck은 잘 sh습니다. 오케이, OSX에서 실패한다는 것을 분명히 할 것입니다.
terdon

이것은 로컬에서만 작동합니다. 이 방법을 사용하여 원격 클라이언트에서 어떤 터미널 에뮬레이터가 사용되고 있는지 파악할 수 없습니다. 가장 좋은 대답은 에뮬레이터 응용 프로그램을 추론하기 위해 $ TERM_PROGRAM (@DanielBeck의 답변에 언급 된) 및 $ XTERM_VERSION과 같은 변수를 찾는 것입니다.
Chris Page

0

부모 프로세스의 이름이나 경로를 얻는 이식 가능한 방법은 다음과 같습니다.

iTerm 2 :

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

우분투의 그놈 터미널 :

$ 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의 명령과 리눅스에서 procps의 구현에서 15 자로 잘립니다 명령 이름의 전체 경로입니다.


iTerm에서 시험을 보았는데 login명령을 실행하기 위해 프로파일을 사용자 정의 했습니까 login -fp danielbeck?
Daniel Beck
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.