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.
Réponses
Trop de publicités?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.
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 .
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.
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