Antworten:
Diese Funktion sollte den Job erledigen:
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
. Habe bash v4.2.24, python v2.7.3 wenn es hilft.
Versuche dies:
echo $TERM
Dies ist maßgeblicher, kann jedoch von Ihren Programmen durcheinander gebracht werden. Allerdings steht auf meinem xterm
und auf ttys linux
, was meiner Meinung nach für Linux Console steht.
$TERM
ist eine Variable, die sich auf die Spezifikation bezieht, die vom verwendeten Terminal-Emulator selbst gemeldet wurde, nicht auf den eigentlichen Emulator. Beispielsweise echo $TERM
kehrt auf meinem System zurück xterm
, obwohl ich tatsächlich lxterminal ausführe. Was gerade passiert, ist die lxterminale Selbstmeldung der xterm Compliance. lxterminal ist nicht vollständig xterm-konform, Sie müssen also aufpassen. Die Spezifikationsdateien befinden sich normalerweise in /usr/share/terminfo
.
Sie können den Namen des Terminalemulators abrufen, indem Sie den Namen des übergeordneten Prozesses angeben. Daher funktioniert es mit jedem Terminalemulator.
In bash, zsh usw .:
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Mit Fischschale:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Auf vielen Linux - System echo $TERM
Rückkehr xterm
siehe stazher Beitrag oben.
Gehen Sie folgendermaßen vor, um das eigentliche Terminal in Betrieb zu nehmen:
1: Schließen Sie alle aktuell ausgeführten Terminalinstanzen.
2: Öffnen Sie das neue Terminal wie gewohnt.
3: Befehl wie folgt eingeben:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: Return sollte etwa so aussehen:
lxterminal --geometry=135x20
Hier ist eine Aufschlüsselung:
Also: ps
ist "Prozessstatus"
Die Option ps -o
ist Mit der durch Leerzeichen oder Kommas getrennten Liste der angegebenen Schlüsselwörter verknüpfte Informationen anzeigen. Klingt kompliziert, ist aber nicht wirklich. (Leerzeichen oder Komma) getrennt (Liste der Schlüsselwörter) angegeben.
(Liste der Schlüsselwörter) ist also 'cmd='
nur ein Schlüsselwort in der Liste. Bitten Sie einfach darum, den Befehl zum Öffnen des Terminals anzuzeigen.
ps-Option -p
ist "nach Prozess-ID" Wow, das ist eine sehr schöne Option für ps. Das Problem ist, dass Sie diese Prozess-ID an ps übergeben müssen. Wie bekomme ich die Prozess-ID? Wir packen den Ausdruck aus $(ps -o 'ppid=' -p $$)
Hier müssen wir anfangen, etwas tiefer zu denken. Ich wünschte, ich hätte diesen Bash-Einzeiler erfunden, aber ich tat es nicht. Ich glaube, ich habe es irgendwo von https://wiki.archlinux.org/ gestohlen , ich konnte es nicht wiederfinden. Diese Jungs sind großartig, aber oft kann ich nicht verstehen, was sie zu tun sagen, bis sie viel gelernt haben. Was wir tun können, ist es jetzt zu verstehen, weil ich es erklären werde.
Wir wissen $
also, dass Expansionsoperator in der Bash ist. Ich denke gerne "auspacken". Also $(foo -opt bar)
wird "foo -opt bar" ausgepackt oder erweitert. Aber in der Bash (...)
öffnet eine einzelne runde Klammer die Unterschale.
So $(foo -opt bar)
erweitert "foo -opt bar" als Lauf in Tochter Shell . Sehr seltsam und schwer zu verstehen.
OK, jetzt führen wir wieder einen fast identischen Befehl aus, ps -o 'ppid=' -p $$
aber dieses Mal zeigt uns ps, process status, was er in der Instanz der Tochter-Shell sehen kann .
-o
Liste der Schlüsselwörter, nur ein Schlüsselwort wie zuvor, aber ppid=
dies fragt direkt nach der Prozess-ID der übergeordneten Shell !! Aus INNERHALB DER TOCHTERSCHALE! Sehr schlau, ja? Ich bin so aufgeregt, wenn ich das verstehen kann!
-p
Auch hier steht "by process id" und in bash $$
die Prozess-ID.
Wenn Sie ps -o 'ppid=' -p $$
oder einen anderen Befehl aufrufen , der $$
direkt von der ersten Shell angefordert wird, könnte er pid = 1 oder die pid von xWindow oder Ihrem Desktop-Programm sagen, oder Sie erhalten möglicherweise die tatsächliche pid der Shell. Wenn Sie mehrmals fragen, erhalten Sie möglicherweise jedes Mal eine andere Antwort!
Aber wenn Sie eine Tochter anrufen und sie fragen, wer Ihr Vater ist, wird sie es Ihnen sagen! Sehr schlau. Ich wünschte, ich könnte solch ein Genie sein, um diese Methode zu erfinden.
Verwenden pstree
und awk
ist der einfachste Weg:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
of $$
(dem aktuellen Prozess) an.Die pstree
Argumente:
-s
: Zeigt die Eltern eines Prozesses an-A
: Ausgabe in reinem ASCII anzeigen.Das awk
Tool scannt ein Muster und -F
Argument wird verwendet, um die Prozesse zu teilen.
'{ print $2 }'
wird festgelegt, dass awk
nur das 2. Übereinstimmungsmuster (in diesem Fall der Name des Terminalemulators) ausgegeben werden soll.$2
? In meinem Fall ist das, in das geleitet awk
wird, tatsächlich systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
anstelle des Terminals, das ich benutze.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Sie haben Recht, ich habe nur die Überschriftenfrage beantwortet, nicht die Frage im Text. Also los, und Bob ist dein Onkel.
Ich bin mir nicht sicher, worum es bei dem Fallwechsel ging, wie oben in einer Antwort gezeigt. Ein solcher Fallschalter ist nicht erforderlich. Mein ~ / .bashrc-Skript ist eigentlich nur eine einfache Zeile, alle Echo-Befehle dienen nur dem Spaß. Wie erklärt man...
Jeder Begriff liest beim Starten ~ / .bashrc und führt alle Befehle aus, die er in .bashrc sehen wird. Unabhängig davon, welcher Begriff aufgerufen wird, liest er .bashrc und führt die Befehle aus. In .bashrc ist daher nur die Struktur erforderlich, um das Verhalten des einen oder anderen Begriffs zu ändern oder auszuschließen. Gewünschtes Verhalten ist, dass jeder Term den gleichen Befehl ausführt, daher ist der case-Schalter nicht erforderlich. Terminal selbst wird Ihnen mitteilen, wie er angerufen wurde, sodass keine Unterscheidung erforderlich ist.
Anmerkung (1) Ich habe nicht auf Guake getestet, aber es funktioniert für alle anderen, die in der ersten Antwort von jlliagre erwähnt wurden.
Hinweis (2) Aufgrund der Formatierung im Markdown für Wiki können Sie nicht wie gezeigt ausschneiden und einfügen. Sie müssen jedes Backtick löschen , einschließlich der unterstrichenen Zeichen, und das tatsächliche Backtick ohne Leerzeichen vor ps
oder nach dem hinzufügen -p $$)
.
Skript für ~ / .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."
Das hat viel Spaß gemacht. Ich habe dies zu meinem eigenen ~ / .bashrc hinzugefügt.
Wenn Sie Bash verwenden, hilft Ihnen dieser Befehl:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
Wenn Sie ZSH verwendet haben, gibt es eine bessere (schnellere) Lösung, die nur ZSH-integrierte Funktionen verwendet und /proc/$pid/{stat,cmdline}
direkt manipuliert .
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
nach der Definition aufzurufen .