GNU/Linux >> Belajar Linux >  >> Linux

Membunuh Subkulit Secara Diam-diam?

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 jalankan wait in. Pokoknya, Anda tidak perlu menunggu proses melakukan wait jadi tidak masalah.
  • kill $subshell akan membunuh subkulit tetapi tidak sleep jika subkulit telah berhasil memulainya pada saat kill dijalankan. Namun Anda dapat menjalankan sleep dalam proses yang sama dengan exec
  • 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:

  1. subkulit
  2. sudo sebagai anak 1
  3. wpa_supplicant (yang sebelumnya menjalankan stdbuf) sebagai anak dari 2
Terkait:Tombol "Bunuh proses terbesar"?

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?


Linux
  1. Cara mematikan proses zombie di Linux

  2. Mengarahkan Output Subkulit ke Proses?

  3. Proses Keturunan?

  1. Cara Membunuh Proses yang Berjalan di Linux

  2. bunuh:perintah tidak ditemukan

  3. Paksa wget ke batas waktu

  1. bunuh Contoh Perintah di Linux

  2. Bunuh sesi layar terpisah

  3. Apa yang dilakukan kill -- -0?