답변:
이 기능은 다음 작업을 수행해야합니다.
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
bash: [: too many arguments
합니다. 도움이된다면 bash v4.2.24, python v2.7.3을 얻었습니다.
이 시도:
echo $TERM
이것은 더 권위적이지만 프로그램에 의해 엉망이 될 수 있습니다. 그러나 내 경우에는 xterm
ttys에서는 linux
이며 Linux 콘솔을 의미한다고 생각합니다.
$TERM
는 실제 에뮬레이터 자체가 아니라 사용중인 터미널 에뮬레이터에서 자체보고 한 사양을 나타내는 변수입니다. 예를 들어, 내 시스템에서 실제로 lxterminal을 실행하고 있지만 echo $TERM
반환합니다 xterm
. lxterminal 자체 보고서 xterm 준수가 발생합니다. lxterminal은 실제로 완전히 xterm을 준수하지 않으므로 조심해야합니다. 사양 파일은 일반적으로에 있습니다 /usr/share/terminfo
.
부모 프로세스 이름을 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/^.* //')
많은 리눅스 시스템에 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을 얻을 수 있습니다. 여러 번 물어 보면 매번 다른 답변을 얻을 수 있습니다!
그러나 당신이 딸을 불러서 그녀에게 "당신의 아빠는 누구입니까?" 매우 영리한. 이 방법을 발명 할 수있는 천재가 되길 바랍니다.
사용 pstree
하고 awk
가장 쉬운 방법입니다.
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
의 $$
합니다 (atual 프로세스).pstree
인수 :
-s
: 프로세스의 부모를 표시-A
: 순수한 ASCII로 출력을 표시합니다.이 awk
도구는 패턴을 스캔하고 -F
인수를 사용하여 프로세스를 분할합니다.
'{ print $2 }'
하도록 지시합니다 awk
.$2
합니까? 로에서 파이프 무엇 내 경우에, awk
실제로 systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
사용중인 터미널 대신 사용합니다.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
당신은 맞습니다, 나는 본문 질문이 아닌 헤드 라인 질문에 대해서만 답했습니다. 자 여기 가서 밥의 아저씨.
위의 한 답변에서 사례 전환에 대해 잘 모르겠습니다. 이러한 경우 스위치는 필요하지 않습니다. 내 ~ / .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에 추가했다.
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
}
container
정의 후에 실제로 함수를 호출하는 것을 잊지 마십시오 .