Réponses:
Cette fonction devrait faire le travail:
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
. Got bash v4.2.24, python v2.7.3 si cela aide.
Essaye ça:
echo $TERM
Cela fait plus autorité, mais pourrait être gâché par vos programmes. Cependant sur le mien, il dit xterm
et sur ttys, il dit linux
, ce qui, je pense, signifie Linux Console.
$TERM
est une variable qui fait référence à la spécification telle que rapportée par l'émulateur de terminal que vous utilisez, et non à l'émulateur lui-même. Par exemple, sur mon système, echo $TERM
renvoie xterm
même si j'utilise en fait lxterminal. Ce qui se passe, c'est la conformité Xterm de lxterminal. lxterminal n'est pas réellement entièrement compatible avec xterm, vous devez donc faire attention. Les fichiers de spécifications se trouvent généralement dans /usr/share/terminfo
.
Vous pouvez obtenir le nom de l'émulateur de terminal en saisissant le nom du processus parent. Par conséquent, cela fonctionne avec chaque émulateur de terminal.
En bash, zsh, etc.:
basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Avec coquille de poisson:
basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \ -f 4) | tail -1 | sed 's/^.* //')
Sur de nombreux echo $TERM
retours de système Linux, xterm
voir le message Stazher ci-dessus.
Pour utiliser le terminal réel, procédez comme suit:
1: Fermez chaque instance de terminal en cours d'exécution.
2: Ouvrez un nouveau terminal en utilisant votre méthode habituelle.
3: Entrez la commande comme suit:
ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)
4: Le retour devrait être quelque chose comme ça:
lxterminal --geometry=135x20
Voici la ventilation:
Donc: ps
est "l'état du processus"
L'option ps -o
est Afficher les informations associées à la liste de mots clés spécifiée par des espaces ou des virgules. Cela semble compliqué, mais ce n'est pas vraiment le cas. (espace ou virgule) séparé (liste de mots-clés) spécifié.
Ainsi, (liste de mots clés) n'est 'cmd='
qu'un seul mot clé dans la liste. Donc, il suffit de demander à afficher la commande pour ouvrir le terminal.
L'option ps -p
est "by process id" Wow, c'est une très bonne option pour ps. Le problème est que vous devez transmettre à ps cet identifiant de processus. Alors, comment obtenir l'identifiant du processus? Nous déballons l'expression $(ps -o 'ppid=' -p $$)
Ici, nous devons commencer à réfléchir un peu plus profondément. J'aimerais avoir inventé ce bash one-liner, mais je ne l'ai pas fait. Je pense que je l'ai volé quelque part sur https://wiki.archlinux.org/ , je n'ai pas pu le retrouver. Ces gars-là sont géniaux, mais plusieurs fois je ne peux pas comprendre ce qu'ils disent de faire qu'après beaucoup d'études. Ce que nous pouvons faire, c'est le comprendre maintenant, car je vais vous l'expliquer.
nous savons donc $
est opérateur d'expansion dans bash. J'aime penser "déballer". Donc, $(foo -opt bar)
déroulera ou développera "foo -opt bar". Mais en bash, une seule accolade ronde (...)
ouvre la sous-coque.
Ainsi, $(foo -opt bar)
développe "foo -opt bar" comme exécuté dans le shell fille . Très bizarre et difficile à comprendre.
OK, maintenant nous exécutons à nouveau une commande presque identique, ps -o 'ppid=' -p $$
mais cette fois ps, l'état du processus, nous montre ce qu'il peut voir à partir de l'instance de shell fille .
-o
liste de mots clés, un seul mot clé comme avant, mais ppid=
cela demande directement l'ID de processus du shell parent !! De DANS LA FILLE DE SHELL! Très intelligent, oui? Je suis tellement excité quand je peux comprendre ça!
-p
encore une fois, "par l'ID de processus" et en bash $$
est l'ID de processus.
Si vous appelez ps -o 'ppid=' -p $$
, ou toute autre commande demandant $$
directement à partir du premier shell, il pourrait dire pid = 1, ou le pid de xWindow, ou à partir de votre programme de bureau, ou vous obtiendrez peut-être un pid réel de shell. Si vous demandez plusieurs fois, vous obtiendrez peut-être une réponse différente à chaque fois!
Mais, si vous invoquez une fille et lui demandez "Who's your Daddy", elle vous le dira! Très intelligent. J'aimerais pouvoir être un tel génie pour inventer cette méthode.
Utiliser pstree
et awk
est le moyen le plus simple:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
de $$
(le processus atuel).Les pstree
arguments:
-s
: afficher les parents d'un processus-A
: affiche la sortie en ASCII pur.L' awk
outil analyse un modèle et un -F
argument est utilisé pour diviser les processus.
'{ print $2 }'
indique de awk
ne sortir que le deuxième modèle de correspondance (dans ce cas, le nom de l'émulateur de terminal).$2
? Dans mon cas, ce qui est canalisé awk
est en fait systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
place du terminal que j'utilise.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Vous avez raison, je n'ai fait que répondre à la question principale, pas à la question dans le corps. Alors voilà, et l'oncle de Bob.
Je ne sais pas de quoi parlait le changement de cas, dans une réponse ci-dessus. Un tel changement de boîtier n'est pas nécessaire. Mon script ~ / .bashrc n'est en fait qu'une simple ligne, toutes les commandes d'écho sont juste pour le plaisir. Comment expliquer...
Tout terme au démarrage lit ~ / .bashrc et exécute toutes les commandes qu'il verra dans .bashrc. Ainsi, quel que soit le terme appelé, il lira .bashrc et exécutera les commandes, donc seule la structure nécessaire dans .bashrc serait de modifier le comportement ou d'exclure un terme ou un autre. Le comportement souhaité est que chaque terme exécute la même commande, donc le commutateur de casse n'est pas nécessaire. Terminal lui-même vous dira comment il a été appelé, il n'est donc pas nécessaire de faire la différence.
Remarque (1) Je n'ai pas testé pour guake, mais fonctionne pour tous les autres mentionnés dans la première réponse par jlliagre.
Remarque (2) En raison du formatage dans le démarquage pour le wiki, vous ne pouvez pas couper et coller comme indiqué. Vous devez supprimer chaque backtick , y compris pour supprimer les caractères soulignés, et ajouter le backtick réel, sans espace avant ps
ou après le -p $$)
.
script pour ~ / .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."
C'était très amusant. J'ai ajouté ceci à mon propre ~ / .bashrc.
si vous utilisez bash, je pense que cette commande vous aidera:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
Si vous utilisiez ZSH, il existe une meilleure solution (plus rapide), qui n'utilise que les modules internes ZSH et manipule /proc/$pid/{stat,cmdline}
directement.
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
après la définition.