私はこのようなことを達成したいQ&Aしかし、サブシェルの場合。私が試している最小限の例は次のとおりです。
(subshell=$BASHPID
(kill $subshell & wait $subshell 2>/dev/null) &
sleep 600)
echo subshell done
subshell done
次の代わりにリターンのみを作成するにはどうすればよいですか?
./test.sh: line 4: 5439 Terminated ( subshell=$BASHPID; ( kill $subshell && wait $subshell 2> /dev/null ) & sleep 600 )
subshell done
編集:ここで私の用語が間違っている可能性があります。サブシェルとは、最初の角かっこセット内のプロセスを意味します。
修正する:
文脈を把握するために、実際のプログラムの一部を公開したかった。上記の内容を単純化すると、次のようになります。
# 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
ベストアンサー1
メモ:
wait $subshell
$subshell
実行中のプロセスの子ではないため、機能しませんwait
。とにかくこれを行うプロセスを待たないので、wait
実際には重要ではありません。kill $subshell
サブシェルは終了しますが、sleep
サブシェルの実行中に正常に起動した場合は終了しません。ただし、同じプロセスでkill
実行できますsleep
exec
- SIGTERM の代わりに SIGPIPE を使用すると、メッセージを回避できます。
- リストコンテキストで引用されていない変数はにあります
bash
。
すべてを言うと、次のことができます。
(
subshell=$BASHPID
kill -s PIPE "$subshell" &
sleep 600
)
echo subshell done
(サブシェルだけでなくシャットダウンしたい場合sleep 60
に置き換えてください。この場合、サブシェルをシャットダウンしたときにサブシェルが実行されるまでの時間さえない場合があります。)exec sleep 60
kill
sleep
sleep
とにかく、あなたがそれで何を達成したいのか分かりません。
sleep 600 &
sleep
それが必要な場合(またはメインシェルでプロセスを非表示にし(sleep 600 &)
たい場合sleep
)、バックグラウンドで実行する方がより安定したアプローチになります。
今実際の状況で
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
コマンドを実行する場合は、子プロセスをsudo
作成してコマンドを実行します(状態を記録するか、後でいくつかのPAMセッション操作を実行する必要がある場合にのみ)。stdbuf
ただし、同じプロセスで実行されるため(残りのスクリプトに加えて)祖先には3つのプロセスがありますwpa_supplicant
。wpa_supplicant
- サブシェル
- 1歳の時 sudo
- wpa_supplicant(stdbufを実行する前)を2の子として使用する
1人を殺すと自動的に2人が死ぬことはありません。しかし、2つを殺すと、傍受できないSIGKILLのような信号が来ない限り、受信した信号を実行するコマンドに渡すsudo
ため、3つが死にます。
とにかくここで殺したいのはサブシェルではなく、3つまたは少なくとも2つです。
スクリプトが実行中で、root
残りのスクリプトはそうでない場合は簡単に終了できません。
kill
完了する必要があるため、root
以下が必要です。
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"
}'
これは、私たちが使用したようにwpa_supplicant
サブシェルと同じプロセスで実行されます。$BASHPID
exec
パイプを介してpidを取得し、kill
rootとして実行します。
もう少し待つ覚悟をしていたら、
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"
SIGPIPE を使用して自動的に終了しますwpa_supplicant
(システムによって、権限の問題はありません)。次回grep
消えたら、そのパイプに何かを書き込みます。
sudo
一部のシェル実装では、1つが返されるのを待たずgrep
(SIGPIPEDが受信されるまでバックグラウンドで実行されるようにします)、1つが返されるのを待たない構文を使用してこれを実行することもbash
できます。grep ... <(sudo ...)
bash
sudo
grep
詳細については、次を参照してください。一致するものを見つけた後、Grepはゆっくり終了しますか?