Cegah layar GNU mengakhiri sesi setelah skrip yang dijalankan berakhir

35

Saya mencoba untuk memaksa layar GNU untuk membuat terminal "virtual", tanpa melampirkannya, jalankan skrip di dalamnya dan TIDAK mengakhiri sesi begitu skrip berakhir.

Saya mencoba banyak kombinasi, termasuk:

screen -dmS udplistener /share/Sys/autorun/start_udp_listeners.sh

atau

screen -S udplistener -X /share/Sys/autorun/start_udp_listeners.sh

dan tidak ada yang bekerja. Saya mendapatkan sesi tanpa skrip dieksekusi, skrip dieksekusi, tetapi sesi dihentikan setelah selesai atau saya mendapatkan kesalahan "Tidak ada sesi layar ditemukan".

Apa yang saya coba pada dasarnya adalah menjalankan pendengar UDP, ditulis dalam PHP dan membuatnya bekerja dalam infinte loop (jangan putus mendengarkan). Ya - Saya bisa menjalankan skrip PHP &di akhir, memaksa PHP CLI dijalankan sebagai daemon. Masalahnya adalah, bahwa saya menggunakan sepotong sampah yang disebut server (QNAP - tidak pernah membeli sampah ini!) Yang sepertinya mengabaikan ini. Segera setelah saya keluar dari sesi SSH, skrip berhenti.

Jadi screensepertinya menjadi satu-satunya pilihan. Tapi saya tidak mengerti, mengapa ini mengakhiri sesi setelah dieksekusi perintah atau skrip berakhir?

EDIT : Saya juga mencoba contoh yang ditemukan di Internet:

screen -dmS name
screen -S name -p windowname -X stuff 'mc
'

Tidak ada kekurangan! Setelah melampirkannya ( screen -R name) Saya melihat bahwa Komandan Tengah Malam belum dieksekusi. Meskipun contoh penulis katakan, itu akan menjadi.

Trejder
sumber
Cara Anda memohon screen, Anda hanya membuat satu jendela untuk menjalankan satu perintah. Ketika perintah keluar, jendela ditutup dan screentidak ada lagi yang harus dilakukan, jadi itu keluar.
jw013
Jadi ... adakah cara untuk membuka dua jendela (hanya menggunakan baris perintah, tanpa kombinasi keyboard), satu untuk menjalankan skrip dan kedua untuk mencegah screendari penutupan? BTW: Saya masih belum mengerti! Jika saya menelepon screen -dmS name, saya membuat jendela terpisah, yang juga tidak ada hubungannya. Tetapi itu tidak ditutup secara otomatis! Tetapi ketika saya ingin mengeksekusi sesuatu di layar terpisah itu, itu berakhir setelah eksekusi dilakukan. Mengapa? Saya tidak melihat logika di sini. Dapat membuat jendela tidak melakukan apa-apa, tetapi tidak bisa membuat jendela melakukan sesuatu dan kemudian tidak melakukan apa-apa?
trejder
2
Ketika Anda memulai jendela tanpa menentukan perintah, itu bukan " tidak melakukan apa-apa". "Sesuatu" yang dilakukannya menjalankan shell interaktif, yang tidak keluar sampai Anda keluar secara manual.
jw013
Keren! Terima kasih atas penjelasannya! Jadi ... kembali ke pertanyaan ... apakah ada cara untuk menjalankan perintah di dalam layar / jendela terpisah dan TIDAK untuk mengakhiri sesi itu, setelah eksekusi perintah berakhir? Lihat juga pertanyaan yang diperbarui. Terima kasih.
trejder
Skrip ini mengeksekusi dua pendengar UDP yang ditulis dalam PHP. Meskipun keduanya dieksekusi sebagai daemon (dengan &di akhir), karena server buggy (QNAP), mereka dihentikan ketika sesi berakhir (saya diberitahu, mereka seharusnya tidak di Linux normal, jika dieksekusi dengan &). Jadi saya tidak ingin melakukan apa pun setelah start_udp_listeners.shselesai, hanya bagaimana mencegah sesi tidak diakhiri. Selama tidak, pendengar PHP saya berfungsi dengan baik.
trejder

Jawaban:

42

Agar layar tetap sibuk setelah skrip selesai, biarkan terus-menerus sesuatu berjalan di jendela. Pilihan paling sederhana untuk "sesuatu" itu mungkin adalah shell interaktif. Inilah salah satu cara untuk melakukannya (dengan asumsi bashsebagai pilihan shell interaktif):

screen -dmS session_name sh -c '/share/Sys/autorun/start_udp_listeners.sh; exec bash'
  • -dm: mulai layar dalam mode terpisah
  • -S: setel nama sesi untuk layar untuk pengambilan yang lebih mudah nanti
  • sh -c '...': alih-alih hanya menjalankan skrip Anda, yang akan berakhir, gunakan sh -cuntuk menjalankan beberapa perintah
  • exec bash: setelah skrip berakhir, shdari atas akan beralih ke shell interaktif ( bash), yang seharusnya tidak pernah keluar sampai sesuatu eksternal berakhir. Ini akan tetap screenterbuka selama bashinstance masih hidup.
jw013
sumber
1
Hm ... sepertinya Anda penyelamat hidupku! :] Memperluas solusi Anda dengan export IGNOREEOF=1untuk mencegah pemutusan hubungan kerja dengan Ctrl + D seharusnya memberi saya solusi yang sempurna, saya sudah mencari sepanjang malam. TERIMA KASIH! :]
trejder
Ini tidak berfungsi pada Debian pada hari ini, -c adalah argumen untuk membaca file
.screenrc
@ToVine berfungsi dengan baik di Debian Stable (Wheezy). Saya menggunakan bash -cmeskipun.
TranslucentCloud
@TranslucentCloud apakah Anda menyertakan seluruh perintah "bash -c ..." dalam tanda kutip? Terakhir kali saya mencobanya (tepat sebelum menulis komentar) itu tidak berhasil untuk saya, tidak yakin mengapa ...
ToVine
@ToVine di sini adalah seluruh perintah saya:screen -LS sauf bash -c "sudo aptitude update && sudo aptitude full-upgrade; exec bash"
TranslucentCloud
2

Saya tidak beruntung dengan sh -craspberry pi 2 saya menjalankan Debian 7.8. Tetapi bash -cberhasil:

Perintah:

/usr/bin/screen -dmS test-screen bash -c "/usr/bin/top; exec bash"
scotty86
sumber
Mungkinkah ini, karena Anda menggunakan (pada Raspberry Pi) shell yang berbeda? The bashdan shtampaknya dua kerang yang berbeda. Itu saja, saya pikir, tapi saya mungkin salah, karena saya pemula di Linux sama sekali.
Trejder
1
sh adalah unix-shell default, itu termasuk dalam raspbian (debian). Perintah sh juga berfungsi, tetapi tidak sh -c dalam kombinasi dengan layar.
scotty86
Terima kasih @ scotty86, saya mengamati hal yang sama di Linux Mint 19 (Ubuntu 18.04) dan berubah sh -cuntuk bash -cmelakukan triknya. Saya tidak mengerti mengapa, baik shdan bashdipasang, jadi aku masih kehilangan tidur di atasnya, tapi setidaknya itu bekerja.
Redsandro
shmungkin menunjuk ke /bin/dashbukan /bin/bash. Debian mengganti shell default dari bashke dashbeberapa tahun yang lalu.
scai