Letakkan proses dimulai dengan! di latar belakang

8

Jika saya melakukan ini dari shell:

$ sleep 100

Saya bisa membuatnya ke latar belakang dengan melakukan:

^Z
$ bg

Dan kemudian terus menggunakan shell saya. Anda bisa mendapatkan efek yang sama dengan menambahkan a &ke akhir perintah, tetapi saya sering lupa ini.

Di Vim, saya sering melakukan:

:!sleep 100

Dan di sini juga, saya sering lupa menambahkan &. Bisakah saya meletakkan proses ini di latar belakang dan terus menggunakan Vim seperti di shell?

Martin Tournoij
sumber
1
Untuk menghindari lupa lagi, Anda dapat meminta Vim untuk menambahkan &setiap waktu: :nnoremap :! :!&<Left>... Tapi tentu saja, kadang-kadang Anda tidak menginginkannya &, dan harus menekan <Del> untuk menghapusnya.
joeytwiddle
@ Joeytwiddle Itu ide yang bagus, dan terdengar seperti sesuatu yang bisa Anda tulis sebagai jawaban, bukan hanya komentar :-)
Martin Tournoij

Jawaban:

5

Seperti yang <C-z>akan menangguhkan Vim sendiri, bukan hanya perintah shell yang diluncurkan, itu tidak akan berfungsi.

Apa yang akan saya lakukan adalah membatalkan perintah yang sudah berjalan lama <C-c>, kemudian meluncurkan kembali perintah yang sama di latar belakang via

:!! &

( :!!Perintah ini berguna untuk memanggil kembali perintah eksternal sebelumnya di sini; Anda juga dapat menggunakan riwayat perintah Ex melalui <Up>.)

Ingo Karkat
sumber
1
Ini tepatnya alur kerja yang saya harap akan saya tingkatkan. Masalahnya adalah Anda harus menutup apa pun yang Anda mulai ...
Martin Tournoij
1

Anda bisa meletakkan perintah di skrip shell yang melatar belakanginya sendiri. Konten, misalnya, mungkin:

#!/bin/sh
sleep 100 &
Jon Carter
sumber
3
Yang tidak akan banyak berguna setelah perintah sudah dimulai.
muru
Maksud saya orang dapat menjalankan skrip shell alih-alih perintah lambat. Memiliki latar belakang itu sendiri meniadakan perlunya mengingat untuk melakukannya pada saat run time. Saya kira saya tidak memahami use case dengan sangat baik. Jika itu adalah perintah yang sama yang saya terus lupa ke latar belakang, saya akan menggunakan skrip shell. Jika ini terjadi dengan perintah sewenang-wenang, saya akan mempertimbangkan membuat kebiasaan beralih ke shell yang sebenarnya untuk melakukannya.
Jon Carter
Saya menggunakan tmuxsecara default, tetapi masalahnya adalah bahwa sesi Vim saya (dengan file terbuka dan semacamnya) masih tidak berguna. Saya bisa beralih ke panel lain, dan menjalankan skrip saya di sana, tetapi itu lebih banyak tindakan daripada :!gitk %misalnya ... Masalahnya dengan menggunakan skrip adalah bahwa saya harus membuat banyak skrip ini untuk setiap perintah yang mungkin. Mungkin itu bukan ide yang buruk untuk beberapa perintah yang paling sering digunakan (seperti gitk& mupdf).
Martin Tournoij
1

Biasanya ketika suatu proses dimulai, Anda tidak memiliki banyak kendali selain menghentikannya ( Ctrl+ c) atau menangguhkannya ( Ctrl+ z, tetapi termasuk proses induknya).

Namun tergantung pada jenis proses dan sistem operasi, berikut adalah beberapa trik yang dapat Anda coba:

  • Mengirim SIGTSTPatau SIGSTOPakan menghentikan proses (sinyal yang sama dikirim oleh Ctrl+ z), dan SIGCONTakan melanjutkan (melanjutkan) proses. Pengujian dengan sleeptidak berfungsi, jadi Anda harus mengujinya dengan perangkat lunak tertentu bagaimana menangani sinyal. Misalnya

    killall -SIGSTOP sleep
    killall -SIGTSTP sleep
    kill -SIGTSTP PID
    

    Proses berhenti SIGSTOP berhenti (tidak dapat ditangkap atau diabaikan)

    SIGTSTP menghentikan proses menghentikan sinyal yang dihasilkan dari keyboard

  • Mengirim SIGHUPke proses. Secara default sinyal ini menghentikan proses, namun jika proses mengimplementasikan sinyal SIGHUP, ia harus melepaskan diri dari mengendalikan tty dan menjalankan kembali di latar belakang dengan id proses baru (biasanya digunakan dengan daemon). Sayangnya banyak aplikasi tidak menanganinya dengan benar dan mati begitu saja (termasuk sleep). Misalnya

    killall -SIGHUP sleep
    

    SIGHUP mengakhiri proses terminal hangup

  • Solusi lain dapat menggunakan alat-alat seperti retty(pasang kembali ke pseudo-tty), detach(melepaskan proses dari terminal), nohup( memutus proses dari terminal ) atau gdb(melampirkan ke proses yang ada -pdan menutup file deskriptornya seperti tty, contoh serupa) ).

Untuk info lebih lanjut, periksa: Kontrol pekerjaan (Unix) - Implementasi di Wikipedia.

Lihat juga: man killatau man sigaction.

kenorb
sumber
Aneh bahwa ini bekerja untuk Anda — seharusnya tidak. STOP / CONT harus berhenti dan melanjutkan proses, tidak lebih. Tidak berfungsi di sini, di konsol vim atau gvim.
derobert
1

Catatan : Jawaban ini sepertinya hanya berfungsi dengan tcshdan fishshells. Saya juga mencoba bash, dash, mksh, dan zsh, dan itu tidak bekerja di sana; Saya tidak yakin mengapa, karena jika saya melakukan tindakan yang sama dari kerang ini tanpa Vim, itu tidak bekerja seperti yang diharapkan ... ( :!perintah dijalankan meskipun shell).

Saya kebetulan menggunakan tcsh, jadi itu berfungsi untuk saya ...

Anda dapat menggunakan :set shell=/bin/tcshuntuk mengatur shell Anda; ini bersifat global. Jadi gunakan saja jika menurut Anda ini fitur yang sangat penting :-)


^Zmengirim SIGTSTPsinyal, Anda dapat mengirim sinyal ini kill, dan kemudian gunakan SIGCONTuntuk melanjutkan (melanjutkan) proses. Ini akan melepaskan proses dari Vim.

Karena sulit untuk ditunjukkan dengan ini sleep(bagaimana Anda tahu bahwa ia telah melanjutkan eksekusi?), Saya akan gunakan gitksebagai contoh (tetapi program GUI akan melakukannya):

Misalnya di Vim:

:!gitk %

Dan kemudian di terminal lain:

$ ps ax | grep gitk
30105 pts/10   S+     0:00 -bin/tcsh -c gitk
30108 pts/10   Sl+    0:00 wish /sbin/gitk --

$ kill -TSTP 30108
$ kill -CONT 30108

Anda tentu saja dapat juga menggunakan killall, atau pkill; sebagai contoh:

$ killall -TSTP wish
$ killall -CONST wish

Anda perlu membuka terminal lain untuk ini, yang tidak ideal, tetapi itu akan memungkinkan Anda untuk terus menggunakan Vim dan proses eksternal Anda.

Martin Tournoij
sumber