10 votes

Bash : Comment déterminer si le terminal est ouvert par une application tierce ?

Je veux que mon bash script (spécifiquement mon ~/.bashrc ) pour faire quelque chose seulement si le terminal a été ouvert par moi directement, et faire autre chose s'il a été ouvert par une application, par exemple VS Code. Comment puis-je déterminer ce qui est le cas ? Existe-t-il une variable pour cela ? Merci d'avance.

11voto

Mark Smith Points 1233

Vous pourriez probablement le faire en remontant l'ascendance du Shell et en déterminant s'il a été lancé par quelque chose qui équivaut à "vous", ou par un autre programme.

Obtenir le PID (process ID) du Shell, et à partir de là son PPID (parent process ID). Continuez jusqu'à ce que vous arriviez à quelque chose qui vous indique d'où il vient. Vous devrez peut-être faire des expériences sur votre système -- en tout cas, je ne sais pas si c'est universel.

Par exemple, sur mon système, obtenir le PID d'un Shell et utiliser ps pour montrer que c'est bash :

$ echo $$
18852
$ ps --pid 18852
  PID TTY          TIME CMD
18852 pts/1    00:00:00 bash

Obtenez le PPID de 18852 :

$ ps -o ppid= -p 18852
18842

Découvrez ce qu'est le PPID (18842) :

$ ps --pid 18842
  PID TTY          TIME CMD
18842 ?        00:00:02 gnome-terminal

Nous pouvons voir que c'est gnome-terminal, c'est-à-dire l'émulateur de terminal / la fenêtre de terminal. Peut-être que cela vous suffit, si votre Shell lancé par l'autre programme ne tourne pas dans une fenêtre d'émulateur de terminal.

Si ce n'est pas assez bien, passez à un autre niveau :

$ ps -o ppid= -p 18842
 2313
$ ps --pid 2313
  PID TTY          TIME CMD
 2313 ?        00:00:00 init

Cela nous dit que gnome-terminal a été lancé par init . Je soupçonne que votre Shell démarré par un autre programme aura quelque chose de différent à cet endroit.

10voto

Sergiy Kolodyazhnyy Points 97292

En ce qui concerne Visual Studio Code, il existe apparemment un moyen de définir variables d'environnement supplémentaires pour le terminal intégré . Donc, configurez Visual Studio pour utiliser cette configuration :

"terminal.integrated.env.linux": {
  "visual_studio": "true"
}

Et dans ~/.bashrc :

if [ -n "$visual_studio" ]; then
    # do something for Visual Studio
else
    # do something else for other types of terminal
fi

En général, vous pouvez vous fier à l'environnement donné à la fonction bash processus. Par exemple, le site $TERM variable et lancer un programme similaire if..then...else...fi branche pour [ "$TERM" = "xterm" ] ou autre chose. Au cas par cas, vous pouvez étudier les différences dans l'environnement en exécutant le programme env dans chaque console, sauvegardez-le dans un fichier comme dans env > output_console1.txt et diff output_console1.txt output_console2.txt comme suggéré par dessert dans les commentaires .

2voto

linuxuser27 Points 4095

Si vous parlez d'une application tierce spécifique, utilisez une variable d'environnement. La plupart des programmes transmettent l'intégralité de l'environnement inchangé lorsqu'ils fork+exec de nouveaux processus.

Donc, démarrer cette application avec une var env personnalisée que vous pouvez vérifier pour . par exemple, créer un alias comme alias vs=RUNNING_FROM_VSCODE=1 VSCode ou faire un script enveloppant comme ceci :

#!/bin/sh
export RUNNING_FROM_VSCODE=1
exec VSCode "$@"

Alors dans votre .bashrc vous pouvez faire

if (($RUNNING_FROM_VSCODE)); then
   echo "started from inside VSCode"
   # RUNNING_FROM_VSCODE=0  # optional if you only want the immediate child
fi

Une instruction arithmétique bash (( )) est vrai si l'expression est évaluée à un nombre entier non nul (c'est pourquoi j'ai utilisé la fonction 1 ci-dessus). La chaîne vide (pour une variable env. non définie) est false. C'est bien pour les variables booléennes de bash, mais vous pourriez tout aussi bien utiliser true et le vérifier avec une méthode POSIX traditionnelle

if [ "x$RUNNING_FROM_VSCODE" = "xtrue" ]; then
   echo "started from inside VSCode"
fi

Si votre application vide principalement l'environnement pour ses enfants mais il continue à transmettre $PATH inchangé, vous pouvez l'utiliser dans votre wrapper :

#!/bin/sh
export PATH="$PATH:/dev/null/RUNNING_FROM_VSCODE"
exec VSCode "$@"

et le vérifier avec une recherche de motif comme bash [[ "${PATH%RUNNING_FROM_VSCODE}" != "$PATH" ]] pour vérifier si le fait de supprimer un suffixe de PATH le modifie.

Cela devrait permettre d'effectuer une recherche de répertoire supplémentaire lorsque le programme recherche des commandes externes non trouvées. /dev/null n'est en aucun cas un répertoire sur un système, il peut donc être utilisé en toute sécurité comme un faux répertoire qui donnera rapidement lieu à la création de ENOTDIR si les recherches PATH ne trouvent pas ce qu'elles recherchent dans les entrées PATH précédentes.

1voto

Zalatik Points 196

Voici mes deux cents. Ajoutez-le à votre .bashrc . Remplacer terminals avec vos terminaux préférés et export avec le vôtre.

run_in_terminal(){
  local parent_command="$(ps --no-headers --pid $PPID -o command | awk '{print $1;}')"
  local parent="$(basename $parent_command)"
  local terminals=( gnome-terminal st xterm ) # list your favorite terminal here
  if [[ ${terminals[*]} =~ ${parent} ]]; then
    # Your commands to run if in terminal
    export MY_VAR_IN_TERMINAL="test"
  fi
}
run_in_terminal

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X