Odpowiedzi:
Ta funkcja powinna wykonać zadanie:
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. Dostałem bash v4.2.24, python v2.7.3, jeśli to pomaga.
Spróbuj tego:
echo $TERM
Jest to bardziej autorytatywne, ale może zostać pomieszane przez twoje programy. Jednak w moim przypadku jest napisane, xtermaw ttys - co linux, jak sądzę, oznacza Linuksową konsolę.
$TERMjest zmienną, która odnosi się do specyfikacji zgłoszonej przez emulator terminala, którego używasz, a nie do samego emulatora. Na przykład w moim systemie echo $TERMzwraca, xtermmimo że faktycznie uruchomiłem lxterminal. To, co się dzieje, to samodzielne raportowanie zgodności xterm. lxterminal nie jest w pełni zgodny z xterm, więc musisz uważać. Pliki specyfikacji zwykle znajdują się w /usr/share/terminfo.
Nazwę emulatora terminala można uzyskać, wpisując nazwę procesu nadrzędnego. Dlatego działa z każdym emulatorem terminala.
W bash, zsh itp .:
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Ze skorupką ryby:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
W przypadku wielu systemów linuksowych echo $TERMpowrót xtermpatrz wyżej post.
Aby uzyskać faktyczny terminal w użyciu, wykonaj następujące czynności:
1: Zamknij każdą aktualnie uruchomioną instancję terminala.
2: Otwórz nowy terminal przy użyciu zwykłej metody.
3: Wpisz polecenie w następujący sposób:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: Powrót powinien być taki:
lxterminal --geometry=135x20
Oto podział:
Więc: psjest „stanem procesu”
Opcja ps -oto Wyświetl informacje związane z podaną listą słów kluczowych oddzielonych spacjami lub przecinkami. Brzmi skomplikowanie, ale tak naprawdę nie jest. (spacja lub przecinek) oddzielone (lista słów kluczowych).
Tak więc (lista słów kluczowych) jest 'cmd='tylko jednym słowem kluczowym na liście. Tak, po prostu prosi o wyświetlenie polecenia, aby otworzyć terminal.
opcja ps -pto „według id procesu” Wow, to jest bardzo fajna opcja dla ps. Problem polega na tym, że musisz przekazać do ps ten identyfikator procesu. Jak uzyskać identyfikator procesu? Odwijamy wyrażenie $(ps -o 'ppid=' -p $$)
Tutaj musimy zacząć myśleć nieco głębiej. Szkoda, że nie wymyśliłem tego bash-one-liner, ale nie zrobiłem tego. Chyba go ukradłem gdzieś https://wiki.archlinux.org/ , nie mogłem znaleźć ponownie. Ci faceci są niesamowici, ale wiele razy nie rozumiem, co mówią, dopóki nie przestaną dużo się uczyć. Co możemy zrobić, to zrozumieć to teraz, ponieważ wyjaśnię.
więc wiemy, że $jest operatorem ekspansji w bash. Lubię myśleć „un-wrap”. Tak więc $(foo -opt bar)rozpakuje lub rozwinie „pasek opcji foo -opt”. Ale w skrócie, pojedynczy okrągły klamra(...) otwiera podpowłokę.
Tak, $(foo -opt bar)rozszerza „foo -opt bar” w biegu w powłoce córki . Bardzo dziwne i trudne do zrozumienia.
OK, więc teraz ponownie uruchamiamy prawie identyczne polecenie, ps -o 'ppid=' -p $$ale tym razem ps, status procesu, pokazuje nam, co widzi z poziomu instancji powłoki córki .
-olista słów kluczowych, tylko jedno słowo kluczowe jak poprzednio, ale ppid=pyta bezpośrednio o identyfikator procesu powłoki nadrzędnej !! OD WEWNĘTRZNEJ SKÓRY CÓRKI! Bardzo sprytne, tak? Jestem bardzo podekscytowany, kiedy mogę to zrozumieć!
-pponownie „id procesu” i bash $$to identyfikator procesu.
Jeśli zadzwonisz ps -o 'ppid=' -p $$, lub jakakolwiek inna komenda, która prosi $$bezpośrednio o pierwszą powłokę, może powiedzieć pid = 1, pid z xWindow lub z twojego programu komputerowego, albo możesz uzyskać rzeczywisty pid powłoki. Jeśli pytasz wiele razy, za każdym razem możesz otrzymać inną odpowiedź!
Ale jeśli wezwiesz córkę i zapytasz ją „Who's your Daddy”, ona ci powie! Bardzo mądry. Chciałbym być genialny, jeśli chodzi o wynalezienie tej metody.
Korzystanie pstreei awkjest najłatwiejszym sposobem:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstreeof $$(proces atualny).Te pstreeargumenty:
-s: wyświetl rodziców procesu-A: wyświetla dane wyjściowe w czystym ASCII.awkNarzędzie skanuje wzór i -Fargumentem jest używany do dzielenia procesów.
'{ print $2 }'każe awkwypisać tylko 2. wzorzec dopasowania (w tym przypadku nazwę emulatora terminala).$2? W moim przypadku chodzi o awkto, że systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree...
xfsettingsdzamiast używanego terminala.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Masz rację, odpowiedziałem tylko na główne pytanie, a nie na pytanie w treści. Proszę bardzo, a wujek Boba.
Nie jestem pewien, o co chodziło w przełączniku skrzynek, w jednej odpowiedzi pokazanej powyżej. Taki przełącznik skrzynek nie jest potrzebny. Mój skrypt ~ / .bashrc jest właściwie tylko jedną prostą linią, wszystkie polecenia echa są po prostu dla zabawy. Jak to wyjaśnić...
Każdy termin na początku czyta ~ / .bashrc i wykonuje wszystkie polecenia, które zobaczy w .bashrc. Tak więc, bez względu na to, jaki termin się nazywa, odczyta .bashrc i wykona polecenia, więc tylko struktura potrzebna w .bashrc polegałaby na modyfikacji zachowania lub wykluczeniu jednego lub drugiego terminu. Pożądanym zachowaniem jest wykonanie każdego polecenia w celu wykonania tego samego polecenia, więc zmiana wielkości liter nie jest wymagana. Sam terminal powie ci, jak został powołany, więc nie ma potrzeby różnicowania.
Uwaga (1) Nie testowałem pod kątem guake, ale działa na wszystkie inne wymienione w pierwszej odpowiedzi przez jlliagre.
Uwaga (2) Ze względu na formatowanie w wiki dla wiki, nie możesz wycinać i wklejać jak pokazano. Musisz usunąć każdy backtick , w tym, aby usunąć podkreślone znaki, i dodać rzeczywisty backtick, bez spacji przed pslub po -p $$).
skrypt dla ~ / .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."
To była świetna zabawa. Dodałem to do własnego ~ / .bashrc.
jeśli używasz bash, myślę, że to polecenie pomoże ci:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
Jeśli korzystasz z ZSH, istnieje lepsze (szybsze) rozwiązanie, które wykorzystuje tylko wbudowane ZSH i manipuluje /proc/$pid/{stat,cmdline}bezpośrednio.
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
}
containerpo definicji.