현재 사용중인 터미널 에뮬레이터를 확인하는 방법은 무엇입니까?


15

그놈 터미널과 Guake가 설치되어 있습니다. 이 터미널 에뮬레이터가 시작될 때 다른 시작 메시지가 표시되도록하고 싶습니다. 이것이 달성되도록 .bashrc에 어떤 코드를 작성해야합니까?

답변:


10

이 기능은 다음 작업을 수행해야합니다.

container() {
    pid=$$
    while true; do
        pid=$(ps -h -o ppid -p $pid 2>/dev/null)
        case $(ps -h -o comm -p $pid 2>/dev/null) in
        (gnome-terminal) echo "Running in gnome terminal";return;;
        (xterm) echo "Running in xterm";return;;
        (rxvt) echo "Running in rxvt";return;;
        (python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
        esac
        [[ $(echo $pid) == 1 ]] && break
    done
}
container

좋은 대답입니다! container정의 후에 실제로 함수를 호출하는 것을 잊지 마십시오 .
rosch

나는 이것이 명백 할 것으로 기대했지만 당신은 옳습니다.
jlliagre 2016 년

@jlliagre 나는 코드를 시도했다. 그놈 터미널에서 원활하게 작동하지만 Guake에는 문제가 있습니다. 출력을 제공하지 않습니다. 대신 교착 상태에있는 것처럼 정지합니다. 그것을 사용하려면 Ctrl + C를 사용해야합니다. 코드를 실제로 이해하지 못했기 때문에 코드가 어디에서 잘못되는지 모릅니다.
VedVals

코드가 수정되었습니다. guake가 파이썬에 의해 실행되고 함수가 종료되는 것을 막는 버그가 누락되었습니다. 피드백을 주셔서 감사합니다.
jlliagre

미안 친구, 여전히 잘 작동하지 않습니다. 오류가 발생 bash: [: too many arguments합니다. 도움이된다면 bash v4.2.24, python v2.7.3을 얻었습니다.
VedVals

10

이 시도:

echo $TERM

이것은 더 권위적이지만 프로그램에 의해 엉망이 될 수 있습니다. 그러나 내 경우에는 xtermttys에서는 linux이며 Linux 콘솔을 의미한다고 생각합니다.


2
$TERM는 실제 에뮬레이터 자체가 아니라 사용중인 터미널 에뮬레이터에서 자체보고 한 사양을 나타내는 변수입니다. 예를 들어, 내 시스템에서 실제로 lxterminal을 실행하고 있지만 echo $TERM반환합니다 xterm. lxterminal 자체 보고서 xterm 준수가 발생합니다. lxterminal은 실제로 완전히 xterm을 준수하지 않으므로 조심해야합니다. 사양 파일은 일반적으로에 있습니다 /usr/share/terminfo.
stazher

7

부모 프로세스 이름을 grepping하여 터미널 에뮬레이터 이름을 얻을 수 있습니다. 따라서 모든 터미널 에뮬레이터에서 작동합니다.

bash, zsh 등에서 :

basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

생선 껍질 포함 :

basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

그러나 이것은 터미널 에뮬레이터가 시작될 때 프로그램 인수를 포착한다는 점에 유의하십시오.
Robobenklein 2016 년

SSH를 사용하여 연결하면 작동합니까?
user3731622

@ user3731622 그렇지 않습니다! 클라이언트에서 전달해야합니다.
Enrico

2

많은 리눅스 시스템에 echo $TERM반환 xterm위의 stazher 게시물을 참조하십시오.

실제 터미널을 사용하려면 다음을 수행하십시오.

1 : 현재 실행중인 모든 터미널 인스턴스를 닫습니다.

2 : 일반적인 방법으로 새 ​​터미널을 엽니 다.

3 : 다음과 같이 명령을 입력하십시오.

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)

4 : 반품은 다음과 같아야합니다.

lxterminal --geometry=135x20

고장은 다음과 같습니다.

그래서 : ps"프로세스 상태가"

ps 옵션 -o은 지정된 공백 또는 쉼표로 구분 된 키워드 목록과 관련된 정보를 표시합니다. 복잡해 보이지만 실제로는 아닙니다. (공백 또는 쉼표) 구분 (키워드 목록)이 지정되었습니다.

따라서 (키워드 목록)은 'cmd='목록에서 하나의 키워드입니다. 따라서 터미널을 여는 명령을 표시하도록 요청하는 것입니다.

ps 옵션 -p은 "프로세스 ID 별"입니다. 이것은 ps에 매우 유용한 옵션입니다. 문제는 ps ​​에게이 프로세스 ID를 전달해야한다는 것입니다. 그렇다면 프로세스 ID를 얻는 방법은 무엇입니까? 표현을 풀어 $(ps -o 'ppid=' -p $$)

여기서 조금 더 깊이 생각해야합니다. 나는이 bash one-liner를 발명하기를 원했지만 나는하지 않았다. https://wiki.archlinux.org/에서 어딘가에 훔쳐서 다시 찾을 수 없다고 생각합니다. 그 사람들은 굉장하지만, 많은 연구를 마칠 때까지 그들이하는 말을 이해하지 못하는 경우가 많습니다. 우리가 할 수있는 것은 지금 설명하는 것이므로 그것을 이해하는 것입니다.

우리가 알 수 있도록하는 것은 $bash는 확장 연산자입니다. 나는 포장을 풀고 싶다고 생각합니다. 따라서 $(foo -opt bar)"foo -opt bar"를 풀거나 확장합니다. 그러나 bash에서 단일 둥근 괄호는 (...)서브 쉘을 엽니 다.

따라서 daughter shell에서 실행될 때$(foo -opt bar) "foo-opt bar" 확장 합니다. 매우 이상하고 이해하기 어렵다.

자, 이제 우리는 거의 동일한 명령을 다시 실행하고 ps -o 'ppid=' -p $$있지만 이번에는 ps, 프로세스 상태는 딸 쉘 인스턴스 내에서 볼 수있는 것을 보여줍니다 .

-o키워드 목록, 이전과 같이 하나의 키워드, 그러나 ppid=이것은 부모 쉘의 프로세스 ID 직접 요청합니다 ! 딸랑이에서! 매우 영리합니다. 이것을 이해할 수있을 때 너무 흥분됩니다!

-p"프로세스 ID 별"및 bash $$에는 프로세스 ID가 있습니다.

ps -o 'ppid=' -p $$, 또는 $$첫 번째 쉘에서 직접 요청하는 다른 명령 을 호출하면 pid = 1, xWindow 또는 데스크톱 프로그램에서 pid를 말하거나 실제 pid of shell을 얻을 수 있습니다. 여러 번 물어 보면 매번 다른 답변을 얻을 수 있습니다!

그러나 당신이 딸을 불러서 그녀에게 "당신의 아빠는 누구입니까?" 매우 영리한. 이 방법을 발명 할 수있는 천재가 되길 바랍니다.


AU는 한 게시물 내에서 적절한 분류를 허용하지 않습니다. 죄송합니다. 블로그 시스템과 싸우지 않고 여러 게시물을 올리려고하지 않습니다. 어쩌면 당신은 아이디어를 얻을 수 있습니다.
stazher

다른 대답에 정교하고 유익한 의견 것 같다 이 대답 이 아니라 질문에 대한 답변보다는 ... 그것은 당신이 그들 중 하나를 삭제 하나에 당신이 답을 결합 할 수 있다면 좋을하고, 그래서 그것이에 추가합니다 질문에 완전히 대답하십시오. 중간에 선을 그리려면 ----를 사용 하시겠습니까? 버튼도 있습니다.
Zanna

나는 OP 질문에 정확하게 답하고 상세하게 대답했다고 생각합니다. 블로그 편집 시스템을 이해하고 끝내기 전에 당신은 저에게 뛰어 들었습니다. 다운 투표를 가져 오면 익숙해집니다.
stazher 2012 년

1
난 당신에게 점프 생각하지 않습니다, 난 그냥 검토를하고 ... 귀하의 게시물을 더 완벽하게 해 주셔서 감사합니다
잔나

당신의 응답을 주셔서 감사합니다. 미안합니다. 어쩌면 나는 당신에게 뛰어 올랐습니다. 대단히 사과드립니다.
stazher

1

사용 pstree하고 awk가장 쉬운 방법입니다.

pstree -sA $$ | awk -F "---" '{ print $2 }'

설명

  1. 와 프로세스의 트리 표시 pstree$$합니다 (atual 프로세스).
  2. pstree인수 :

    • -s: 프로세스의 부모를 표시
    • -A: 순수한 ASCII로 출력을 표시합니다.
  3. awk도구는 패턴을 스캔하고 -F인수를 사용하여 프로세스를 분할합니다.

  4. 마지막으로 두 번째 일치 패턴 (이 경우 터미널 에뮬레이터 이름) 만 출력 '{ print $2 }'하도록 지시합니다 awk.

확실 $2합니까? 로에서 파이프 무엇 내 경우에, awk실제로 systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree...
엔리코 마리아 드 Angelis의

@EnricoMariaDeAngelis Ya. 관찰 해 주셔서 감사합니다. 필자의 경우 터미널 에뮬레이터는 시스템 서비스에서 직접 초기화됩니다. 코드를 다시 확인하고 수정하여 편집하십시오.
silvadev

키보드 단축키를 사용하여 에뮬레이터를 시작하면 작동하지 않습니다. XFCE에서는 xfsettingsd사용중인 터미널 대신 사용합니다.
Michael Hoffmann

당신이 끝에서 시작하면 잘 작동 :pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
lleaff

0

당신은 맞습니다, 나는 본문 질문이 아닌 헤드 라인 질문에 대해서만 답했습니다. 자 여기 가서 밥의 아저씨.

위의 한 답변에서 사례 전환에 대해 잘 모르겠습니다. 이러한 경우 스위치는 필요하지 않습니다. 내 ~ / .bashrc 스크립트는 실제로 하나의 간단한 줄이며 모든 echo 명령은 재미를 위해 있습니다. 설명하는 방법 ...

시작할 때의 모든 용어는 ~ / .bashrc를 읽고 .bashrc에 표시되는 모든 명령을 실행합니다. 따라서 어떤 용어를 호출하든 .bashrc를 읽고 명령을 실행하므로 .bashrc에 필요한 구조만이 하나의 용어 또는 다른 용어의 동작을 수정하거나 제외하는 것입니다. 원하는 동작은 모든 용어가 동일한 명령을 실행하는 것이므로 대소 문자 전환이 필요하지 않습니다. 터미널은 자신이 어떻게 부름을 받았는지 구별 할 필요가 없습니다.

참고 (1) 나는 구크를 테스트하지 않았지만 jlliagre의 첫 번째 답변에서 언급 된 다른 모든 사람들을 위해 작동합니다.

참고 (2) 위키의 마크 다운 형식으로 인해 그림과 같이 잘라내어 붙여 넣기를 할 수 없습니다. 밑줄 문자 삭제를 포함하여 각 backtick 를 삭제하고 실제 백틱을 추가해야합니다 ps.-p $$) .

~ / .bashrc를위한 스크립트

# show welcome message for actual terminal in use
echo "Welcome.  You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."

이것은 매우 재미 있었다. 나는 이것을 ~ / .bashrc에 추가했다.


Tilda에서 테스트 한 Note (1)에 따라 정상적으로 작동합니다. Guake는 Tilda와 비슷하지만 파이썬으로 작성되었으므로 여전히 Guake에 대해 알지 못합니다.
stazher

0

bash 사용하는 경우이 명령이 도움이 될 것입니다.

which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))


0

ZSH를 사용하는 경우 ZSH 내장 만 사용하고 /proc/$pid/{stat,cmdline}직접 조작하는 더 나은 (빠른) 솔루션이 있습니다.

get-terminal-emulator() {
    if [[ $TTY = "/dev/tty"* ]]; then
        echo "linux-console"
        return
    fi
    local pid=$$ name=''
    while true; do
        proc_stat=(${(@f)$(</proc/${pid}/stat)})
        name=${proc_stat[2]//[()]/}
        case "${name}" in
            gnome-terminal|konsole|rxvt|xterm)
                echo "${name}"; return ;;
            python*)
                local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
                if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
                    echo "guake"; return
                fi
                ;;
        esac
        if test "$pid" = "1" -o "$pid" = ""; then
            echo "unknown"
            return
        fi
        pid=${proc_stat[4]}       
    done
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.