Chci implementovat něco takového Q/A, ale pro sub-shell. Zde je minimální příklad toho, co se snažím:
(subshell=$BASHPID
(kill $subshell & wait $subshell 2>/dev/null) &
sleep 600)
echo subshell done
Jak to mohu udělat tak, aby subshell done vrátí místo:
./test.sh: line 4: 5439 Terminated ( subshell=$BASHPID; ( kill $subshell && wait $subshell 2> /dev/null ) & sleep 600 )
subshell done
Edit:Možná se mýlím v terminologii zde, podslupkou myslím proces v první sadě hranatých závorek.
Aktualizace:
Chci zveřejnit úryvek ze skutečného programu pro kontext, výše je zjednodušení:
# 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
Přijatá odpověď:
Poznámka:
wait $subshellnebude fungovat jako$subshellnení potomkem procesu, který spouštítewaitv. Každopádně byste nečekali, až proces provedewaittakže na tom moc nezáleží.kill $subshellse chystá zabít subshell, ale nesleeppokud se subshell podařilo spustit jej do dobykillbyl spuštěn. Můžete však spustitsleepve stejném procesu jakoexec- můžete použít SIGPIPE místo SIGTERM, abyste se vyhnuli zprávě
- nechat proměnnou bez uvozovek v kontextu seznamu má v
bashvelmi zvláštní význam .
Takže když jste to všechno řekli, můžete udělat:
(
subshell=$BASHPID
kill -s PIPE "$subshell" &
sleep 600
)
echo subshell done
(nahraďte sleep 60 s exec sleep 60 pokud chcete kill zabít sleep a nejen subshell, který v tomto případě nemusí mít ani čas spustit sleep v době, kdy ho zabijete).
V každém případě si nejsem jistý, čeho tím chcete dosáhnout.
sleep 600 &
by byl spolehlivější způsob, jak začít sleep na pozadí, pokud jste to chtěli udělat (nebo (sleep 600 &) pokud jste chtěli skrýt ten sleep proces z hlavního prostředí)
Nyní s vaším skutečným
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
příkaz, všimněte si, že sudo spustí podřízený proces pro spuštění příkazu (i když jen proto, že může potřebovat zaprotokolovat svůj stav nebo poté provést některé úlohy relace PAM). stdbuf nicméně spustí wpa_supplicant ve stejném procesu, takže nakonec budete mít tři procesy (kromě zbytku skriptu) v wpa_supplicant 's předky:
- podshell
- sudo jako dítě 1
- wpa_supplicant (který dříve spouštěl stdbuf) jako dítě 2
Pokud zabijete 1, nezabije to automaticky 2. Pokud však zabijete 2, pokud to není signálem jako SIGKILL, který nelze zachytit, zabije to 3 jako sudo se stane, že předá signály, které obdrží, příkazu, který spustí.
V každém případě to není podshell, který byste zde chtěli zabít, je to 3 nebo alespoň 2.
Nyní, pokud běží jako root a zbytek skriptu není, nebudete ho moci tak snadno zabít.
Potřebovali byste kill provést jako root , takže budete potřebovat:
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"
}'
Tímto způsobem wpa_supplicant poběží ve stejném $BASHPID proces jako subshell, jak jej vytváříme pomocí exec .
Provedeme pid potrubím a spustíme kill jako root.
Všimněte si, že pokud jste připraveni počkat o něco déle,
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"
Měl by wpa_supplicant automaticky zabit pomocí SIGPIPE (systémem, takže žádný problém s oprávněním) příště zapíše něco do této roury za grep je pryč.
Některé implementace shellu by nečekaly na sudo za grep se vrátil (ponechává jej běžet na pozadí, dokud se nespustí SIGPIPE) a s bash , můžete to udělat také pomocí grep ... <(sudo ...) syntaxe, kde bash nečeká na sudo buď za grep se vrátil.
Více na Grep se po nalezení shody pomalu ukončuje?