Je veux que mon script bash (en particulier mon ~/.bashrc
) ne fasse quelque chose que si le terminal a été ouvert directement par moi, et je fais autre chose s'il était ouvert via une application, par exemple. Code VS Comment puis-je déterminer quel est le cas? Y a-t-il une variable pour cela? Merci d'avance.
Vous pouvez probablement le faire en remontant l'ascendance de Shell et en déterminant si elle a été lancée par quelque chose qui équivaut à "vous" ou à un autre programme.
Obtenez le PID (ID de processus) du shell, puis son PPID (ID de processus parent). Continuez jusqu'à ce que vous arriviez à quelque chose qui vous dit d'où ça vient. Vous devrez peut-être expérimenter sur votre système - du moins, je ne sais pas si ce sera universel.
Par exemple, sur mon système, obtenez le PID d'un shell et utilisez ps
pour indiquer qu'il s'agit de 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 la fenêtre émulateur/terminal. C’est peut-être suffisant si votre shell lancé par l’autre programme ne s’exécute pas dans une fenêtre d’émulateur de terminal.
Si cela ne suffit pas, passez à un autre niveau:
$ ps -o ppid= -p 18842
2313
$ ps --pid 2313
PID TTY TIME CMD
2313 ? 00:00:00 init
Cela nous indique que gnome-terminal
a été lancé par init
. Je pense que votre Shell lancé par un autre programme aura quelque chose de différent là-bas.
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 compter sur l'environnement attribué au processus bash
. Par exemple, la variable $TERM
et exécutez une branche if..then...else...fi
similaire pour [ "$TERM" = "xterm" ]
ou quelque chose d'autre. Au cas par cas, vous pouvez étudier les différences d’environnement en exécutant env
dans chaque console, enregistrez-le dans le fichier sous 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 intégralement l'environnement dans leur intégralité lorsqu'ils achètent + exécutent de nouveaux processus.
Donc, démarrez cette application avec une variable personnalisée que vous pouvez vérifier . par exemple. Créez-lui un alias du type alias vs=RUNNING_FROM_VSCODE=1 VSCode
, ou créez un script wrapper ressemblant à ceci:
#!/bin/sh
export RUNNING_FROM_VSCODE=1
exec VSCode "$@"
Ensuite, 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 vraie si l'expression est évaluée à un entier différent de zéro (c'est pourquoi j'ai utilisé 1
ci-dessus). La chaîne vide (pour une variable env non définie) est false. C'est bien pour les variables booléennes bash, mais vous pouvez tout aussi bien utiliser true
et le vérifier avec un POSIX traditionnel
if [ "x$RUNNING_FROM_VSCODE" = "xtrue" ]; then
echo "started from inside VSCode"
fi
Si votre application nettoie principalement l'environnement pour ses enfants , mais transmet toujours $PATH
sans modification, vous pouvez l'utiliser dans votre enveloppe:
#!/bin/sh
export PATH="$PATH:/dev/null/RUNNING_FROM_VSCODE"
exec VSCode "$@"
et vérifiez-le avec une correspondance 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 sans danger faire 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. Vous pouvez donc l'utiliser en tant que répertoire factice qui entraînera rapidement un ENOTDIR
si les recherches PATH ne trouvent pas ce qu'elles recherchent dans les entrées PATH précédentes.
Voici mes 2 cents. Ajoutez-le simplement à votre .bashrc
. Remplacez terminals
par vos terminaux préférés et la commande export
par la 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