Je veux implémenter quelque chose comme ce Q/A mais pour un sous-shell. Voici un exemple minimal de ce que j'essaie :
(subshell=$BASHPID
  (kill $subshell & wait $subshell 2>/dev/null) &
sleep 600)
echo subshell done
 
 Comment puis-je faire en sorte que seul subshell done renvoie au lieu de :
./test.sh: line 4:  5439 Terminated              ( subshell=$BASHPID; ( kill $subshell && wait $subshell 2> /dev/null ) & sleep 600 )
subshell done
 Modifier :je me trompe peut-être sur la terminologie ici, par sous-shell, je veux dire le processus dans le premier ensemble de crochets.
Mise à jour :
Je veux poster l'extrait du programme réel pour le contexte, ci-dessus est une simplification :
# If subshell below if killed or returns error connected variable won't be set
(if [ -n "$2" ];then
      # code to setup wpa configurations here
      # If wifi key is wrong kill subshell
      subshell=$BASHPID
      (sudo stdbuf -o0 wpa_supplicant -Dwext -i$wifi -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 \
        | grep -m 1 "pre-shared key may be incorrect" \
        && kill -s PIPE "$subshell") &
      # More code which does the setup necessary for wifi
) && connected=true
# later json will be returned based on if connected is set
 Réponse acceptée :
Remarque :
wait $subshellne fonctionnera pas comme$subshelln'est pas un enfant du processus que vous exécutezwaitdans. Quoi qu'il en soit, vous n'attendriez pas le processus en faisant lewaitdonc ça n'a pas beaucoup d'importance.kill $subshellva tuer le sous-shell mais passleepsi le sous-shell avait réussi à le démarrer au momentkillÉtait dirigé. Vous pouvez cependant lancersleepdans le même processus avecexec- vous pouvez utiliser SIGPIPE au lieu de SIGTERM pour éviter le message
 - laisser une variable sans guillemets dans les contextes de liste a une signification très spéciale dans 
bash. 
Après avoir dit tout cela, vous pouvez faire :
(
  subshell=$BASHPID
  kill -s PIPE "$subshell" &
  sleep 600
)
echo subshell done
 
 (remplace sleep 60 avec exec sleep 60 si vous voulez le kill tuer le sleep et pas seulement le sous-shell, qui dans ce cas n'a peut-être même pas le temps d'exécuter sleep au moment où vous le tuez).
En tout cas, je ne suis pas sûr de ce que vous voulez réaliser avec ça.
sleep 600 &
 
 serait un moyen plus fiable de commencer à sleep en arrière-plan si c'est ce que vous vouliez faire (ou (sleep 600 &) si vous vouliez cacher ce sleep processus depuis le shell principal)
Maintenant avec votre réel
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
 
 commande, notez que sudo génère un processus enfant pour exécuter la commande (ne serait-ce que parce qu'il peut avoir besoin de consigner son état ou d'effectuer certaines tâches de session PAM par la suite). stdbuf exécutera cependant wpa_supplicant dans le même processus, donc au final vous aurez trois processus (en plus du reste du script) dans wpa_supplicant l'ascendance de :
- le sous-shell
 - sudo en tant qu'enfant de 1 ans
 - wpa_supplicant (qui exécutait auparavant stdbuf) en tant qu'enfant de 2
 
 Si vous tuez 1, cela ne tue pas automatiquement 2. Si vous tuez 2 cependant, à moins que ce ne soit avec un signal comme SIGKILL qui ne peut pas être intercepté, cela tuera 3 comme sudo arrive à transmettre les signaux qu'il reçoit à la commande qu'il exécute.
Dans tous les cas, ce n'est pas le sous-shell que vous voudriez tuer ici, c'est 3 ou au moins 2.
 Maintenant, s'il s'exécute en tant que root et le reste du script ne l'est pas, vous ne pourrez pas le tuer aussi facilement.
 Vous auriez besoin du kill à faire en tant que root , vous aurez donc besoin :
sudo WIFI="$wifi" bash -c '
  (echo "$BASHPID" &&
   exec stdbuf -o0 wpa_supplicant -Dwext -i"$WIFI" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1
  ) | {
    read pid &&
      grep -m1 "pre-shared key may be incorrect" &&
      kill -s PIPE "$pid"
  }'
 
 De cette façon, wpa_supplicant sera exécuté dans le même $BASHPID traiter en tant que sous-shell comme nous en faisons avec exec .
 Nous obtenons le pid à travers le tuyau et exécutons kill en tant que root.
Notez que si vous êtes prêt à attendre un peu plus longtemps,
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 |
  grep -m1 "pre-shared key may be incorrect"
 
 Aurait wpa_supplicant tué automatiquement avec un SIGPIPE (par le système, donc pas de problème d'autorisation) la prochaine fois il écrit quelque chose dans ce tube après grep est parti.
 Certaines implémentations de shell n'attendraient pas sudo après grep est revenu (le laissant fonctionner en arrière-plan jusqu'à ce qu'il soit SIGPIPEd), et avec bash , vous pouvez également le faire en utilisant le grep ... <(sudo ...) syntaxe, où bash n'attend pas sudo soit après grep est de retour.
Plus chez Grep lent à sortir après avoir trouvé une correspondance ?