Saya ingin mengimplementasikan sesuatu seperti T/A ini tetapi untuk sub-kulit. Berikut adalah contoh minimal dari apa yang saya coba:
(subshell=$BASHPID
(kill $subshell & wait $subshell 2>/dev/null) &
sleep 600)
echo subshell done
Bagaimana saya bisa membuatnya hanya subshell done
kembali sebagai ganti:
./test.sh: line 4: 5439 Terminated ( subshell=$BASHPID; ( kill $subshell && wait $subshell 2> /dev/null ) & sleep 600 )
subshell done
Sunting:Saya mungkin salah dalam terminologi di sini, dengan subkulit yang saya maksud adalah proses dalam tanda kurung pertama.
Pembaruan:
Saya ingin memposting cuplikan dari program sebenarnya untuk konteks, di atas adalah penyederhanaan:
# 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
Jawaban yang Diterima:
Catatan:
wait $subshell
tidak akan berfungsi sebagai$subshell
bukan anak dari proses yang Anda jalankanwait
in. Pokoknya, Anda tidak perlu menunggu proses melakukanwait
jadi tidak masalah.kill $subshell
akan membunuh subkulit tetapi tidaksleep
jika subkulit telah berhasil memulainya pada saatkill
dijalankan. Namun Anda dapat menjalankansleep
dalam proses yang sama denganexec
- Anda dapat menggunakan SIGPIPE sebagai ganti SIGTERM untuk menghindari pesan
- meninggalkan variabel tanpa tanda kutip dalam konteks daftar memiliki arti yang sangat khusus di
bash
.
Jadi setelah mengatakan semua itu, Anda dapat melakukan:
(
subshell=$BASHPID
kill -s PIPE "$subshell" &
sleep 600
)
echo subshell done
(ganti sleep 60
dengan exec sleep 60
jika Anda ingin kill
untuk membunuh sleep
dan bukan hanya subkulit, yang dalam hal ini mungkin bahkan tidak punya waktu untuk menjalankan sleep
pada saat Anda membunuhnya).
Bagaimanapun, saya tidak yakin apa yang ingin Anda capai dengan itu.
sleep 600 &
akan menjadi cara yang lebih andal untuk memulai sleep
di latar belakang jika itu yang ingin Anda lakukan (atau (sleep 600 &)
jika Anda ingin menyembunyikan sleep
proses dari shell utama)
Sekarang dengan Anda yang sebenarnya
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
perintah, perhatikan bahwa sudo
tidak menelurkan proses anak untuk menjalankan perintah (jika hanya karena mungkin perlu mencatat statusnya atau melakukan beberapa tugas sesi PAM sesudahnya). stdbuf
namun akan mengeksekusi wpa_supplicant
dalam proses yang sama, jadi pada akhirnya Anda akan memiliki tiga proses (selain sisa skrip) di wpa_supplicant
nenek moyang:
- subkulit
- sudo sebagai anak 1
- wpa_supplicant (yang sebelumnya menjalankan stdbuf) sebagai anak dari 2
Jika Anda membunuh 1, itu tidak secara otomatis membunuh 2. Namun, jika Anda membunuh 2, kecuali dengan sinyal seperti SIGKILL yang tidak dapat dicegat, itu akan membunuh 3 sebagai sudo
terjadi untuk meneruskan sinyal yang diterimanya ke perintah yang dijalankannya.
Bagaimanapun, itu bukan subkulit yang ingin Anda bunuh di sini, ini 3 atau setidaknya 2.
Sekarang, jika dijalankan sebagai root
dan skrip lainnya tidak, Anda tidak akan dapat membunuhnya dengan mudah.
Anda memerlukan kill
untuk dilakukan sebagai root
, jadi Anda memerlukan:
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"
}'
Dengan begitu, wpa_supplicant
akan berjalan di $BASHPID
yang sama proses sebagai subkulit seperti yang kami buat dengan exec
.
Kami mendapatkan pid melalui pipa dan menjalankan kill
sebagai root.
Perhatikan bahwa jika Anda siap untuk menunggu sedikit lebih lama,
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"
Akan memiliki wpa_supplicant
dibunuh secara otomatis dengan SIGPIPE (oleh sistem, jadi tidak ada masalah izin) lain kali itu menulis sesuatu ke pipa itu setelah grep
hilang.
Beberapa implementasi shell tidak akan menunggu sudo
setelah grep
telah kembali (membiarkannya berjalan di latar belakang hingga SIGPIPEd), dan dengan bash
, Anda juga dapat melakukannya menggunakan grep ... <(sudo ...)
sintaks, di mana bash
tidak menunggu sudo
baik setelah grep
telah kembali.
More di Grep lambat untuk keluar setelah menemukan kecocokan?