Existe-t-il un moyen pour un script bash de savoir s'il s'exécute au premier plan ou en arrière-plan, et qu'il peut donc se comporter légèrement différemment dans chaque cas?
Existe-t-il un moyen pour un script bash de savoir s'il s'exécute au premier plan ou en arrière-plan, et qu'il peut donc se comporter légèrement différemment dans chaque cas?
Réponses:
Citant man ps:
Here are the different values that the s, stat and state output
specifiers (header "STAT" or "S") will display to describe the state of
a process.
...
+ is in the foreground process group
Vous pouvez donc effectuer une simple vérification:
case $(ps -o stat= -p $$) in
*+*) echo "Running in foreground" ;;
*) echo "Running in background" ;;
esac
Toutes les solutions précédentes impliquent des processus d'apparition, etc. Très, très moche, car .bashrcest appelé à chaque lancement d'un shell bash, donc ces solutions finissent par lancer des milliers de processus.
Beaucoup plus propre demande bash lui-même: bash a une variable prédéfinie $-qui a "i" si elle s'exécute dans un shell interactif. Par exemple, mettre cela dans votre .bashrc est beaucoup plus propre et beaucoup moins cher et, surtout, cela fonctionnera toujours!
case "$-" in
*i*) # interactive shell
;;
esac
Alors que vous pourriez penser que vérifier si le shell est exécuté en mode interactif donnera le même résultat, en pratique, ce n'est pas le cas. Le concept semble similaire mais est en réalité différent. Vous pouvez exécuter un script interactif dans l' entrée d'alimentation en arrière-plan grâce à expect . Vous pouvez également lancer votre script avec bash avec l' -largument. Nous ne pouvons donc pas compter sur l'interactivité bash pour vérifier si notre script est exécuté en arrière-plan ou au premier plan.
La réponse de devnull est donc correcte . Pour déterminer si le processus s'exécute au premier plan, l'utilitaire ps vérifie si le groupe de processus (pgrp) est le même que l'ID de groupe de processus associé au terminal de contrôle de la session (tpgid) et ajoute un +signe dans la sortie en fonction du processus Etat.
Sachant cela, nous pouvons certainement avoir une version pure bash du test:
#!/usr/bin/env bash
IFS=$' '
retval=($(</proc/$$/stat))
IFS=$' \t\n'
if [[ "${retval[3]}" == "${retval[7]}" ]]; then
echo "Background" > ./result.txt
else
echo "Foreground" > ./result.txt
fi
exit
Dans le code ci-dessus, nous générons le résultat dans un fichier texte car il stdoutn'est pas connecté lorsqu'un processus est exécuté en arrière-plan.
Veuillez noter que les 4e et 8e éléments du tableau correspondent respectivement à pgrpet tpgid( voir la section / proc / [pid] / stat de la page de manuel - man 5 proc).