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 $subshell
nebude fungovat jako$subshell
není potomkem procesu, který spouštítewait
v. Každopádně byste nečekali, až proces provedewait
takže na tom moc nezáleží.kill $subshell
se chystá zabít subshell, ale nesleep
pokud se subshell podařilo spustit jej do dobykill
byl spuštěn. Můžete však spustitsleep
ve 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
bash
velmi 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?