Cara menangguhkan dan membawa latar belakang proses ke latar depan


167

Saya memiliki proses yang awalnya berjalan di latar depan. Saya ditangguhkan oleh Ctrl+ Z, dan kemudian kembali berjalan di latar belakang oleh bg <jobid>.

Saya bertanya-tanya bagaimana cara menunda proses yang berjalan di latar belakang?

Bagaimana saya bisa membawa proses latar belakang ke latar depan?

Sunting:

Proses menghasilkan ke stderr, jadi bagaimana saya akan mengeluarkan perintah fg <jobid>saat proses menghasilkan ke terminal?


1
Anda masih bisa mengetik perintah di terminal yang memuntahkan kesalahan. Teks yang dimuntahkan di STDERR tidak dihitung sebagai input, hanya kunci yang Anda kirim. Ini terlihat membingungkan di layar tetapi berfungsi.
Caleb

@ Caleb: Bahkan ketika proses output ke stdout, saya masih bisa mengetik fg <jobid>untuk membuatnya foreground?
Tim

@Tim: Ya, Anda bisa.
Caleb

Jawaban:


216

Seperti kata Tim, ketik fguntuk membawa proses terakhir kembali ke latar depan.

Jika Anda memiliki lebih dari satu proses yang berjalan di latar belakang, lakukan ini:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 bash
[3]+  Stopped                 vim 23

fg %3untuk membawa vim 23proses kembali ke latar depan.

Untuk menunda proses yang berjalan di latar belakang, gunakan:

kill -STOP %job_id

Sinyal SIGSTOP berhenti (menjeda) suatu proses pada dasarnya dengan cara yang sama Ctrl+ Ztidak.

Contoh: kill -STOP %3.

sumber: Cara mengirim sinyal ke proses di Linux dan Unix dan Cara mengelola pekerjaan latar belakang dan latar depan .


23
sinyal 19 adalah SIGCONTuntukku; Saya menggunakan kill -STOPdan kill -CONTlebih suka mengingat angka-angkanya, tetapi Anda dapat memeriksa kill -luntuk mengingatkan diri sendiri tentang nilai
berguna

Proses menghasilkan ke stderr, jadi bagaimana saya akan mengeluarkan perintah jobdan fg <jobid>saat proses menghasilkan ke terminal?
Tim

1
@Tim Cukup ketik perintah seperti biasa. Selama pekerjaan itu dilatarbelakangi, itu tidak membaca apa yang Anda ketik - shell Anda. Apa yang Anda ketik mungkin terlihat rusak untuk Anda, tetapi shell akan memahaminya dengan baik.
AlexWebr

@AlexWebr: Terima kasih, itu berhasil! (1) Apakah pekerjaan latar belakang tidak menerima input dan output termasuk "Ctrl + Z" dll, kan? (2) Bisakah pekerjaan yang berjalan di latar belakang ditangguhkan secara langsung? Jika ya, bagaimana? Jika tidak, apakah ini harus diubah dulu untuk dijalankan di latar depan sebelum dapat ditangguhkan?
Tim

2
Bisakah pekerjaan yang berjalan di latar belakang ditangguhkan secara langsung ya kill -STOP %job_id
:,

31

Ini harus berlaku untuk semua shell dengan kontrol pekerjaan, yang (sebagian besar) dapat Anda terima begitu saja kecuali berurusan dengan shell yang benar-benar kuno. Ada dalam standar POSIX , jadi bahkan dashmendukung kontrol pekerjaan (saat dijalankan secara interaktif atau dengan -m).

Interaktif

  • Ctrl+ zakan menangguhkan program yang saat ini foregrounded
  • bgakan latar belakang program yang terakhir ditangguhkan
    (digunakan bg %2dengan nomor pekerjaan, yang dapat Anda periksa jobs)
  • fg akan memagari program yang terakhir ditangguhkan

Di zsh, Anda bisa menulis kunci yang mengikat untuk dijalankan secara implisit fgdari prompt melalui Ctrl+ lainnya z:

_zsh_cli_fg() { fg; }
zle -N _zsh_cli_fg
bindkey '^Z' _zsh_cli_fg

Mungkin juga ada cara cerdas untuk secara implisit dijalankan bgpada penangguhan, tetapi tampaknya tidak bijaksana; setidaknya bagi saya, sebagian besar penggunaan Ctrl+ saya zadalah karena Ctrl+ cgagal keluar; Saya ingin mengikutinya dengan misalnya kill %1daripada bg, dan saya tentu saja tidak ingin default untuk membunuh! (Logika ini juga meluas ke mengapa saya tidak lagi menggunakan pengikatan kunci ini: Jika saya memalu Ctrl+ zuntuk menghentikan proses, hal terakhir yang saya inginkan adalah melanjutkan!)

Non-interaktif

Jika Anda menggunakan instance shell yang berbeda (atau pengguna yang berbeda, terkadang termasuk sudoperintah), Anda kemungkinan tidak akan dapat menggunakan nomor pekerjaan.

Anda masih dapat bertindak pada proses lain setelah Anda mengetahui ID prosesnya (PID). Anda bisa mendapatkan PID dengan pgrep …, atau ps aux |grep …(atau dari shell yang sama jobs -l,, atau $!) dan kemudian Anda dapat menjalankan:

kill -STOP $PID  # suspend
kill -CONT $PID  # continue (resume)

Jika Anda tidak tahu ID proses dan tidak khawatir tentang menangguhkan instance proses lainnya dengan nama, Anda dapat mengirimkan sinyal ke salah satu dari ini:

killall -STOP program_name
pkill -STOP program_name
pkill -f -STOP program_name_or_args

Sebuah CONTsinyal untuk program berhenti dengan Ctrl+ z(dan tidak bg'd) akan melanjutkan kemajuannya (di latar depan), sama seperti jika Anda adalah untuk fgitu.

Re: Standard Error

Hasil edit untuk pertanyaan ini menanyakan tentang kesalahan standar:

Proses menghasilkan ke stderr, jadi bagaimana saya akan mengeluarkan perintah fg <jobid>saat proses menghasilkan ke terminal?

Kecuali jika pekerjaan tersebut memiliki komponen yang berlatar belakang (atau seluruh pekerjaan dilatar belakangi, mungkin melalui kill -CONT), Anda seharusnya tidak benar-benar melihat output saat ditangguhkan.

Jika masih mengeluarkan data (baik itu ke keluaran standar atau kesalahan standar), tentu saja akan membuat terminal Anda berantakan secara visual, tetapi semua output itu akan diabaikan karena itu bukan bagian dari input Anda. Ini mungkin membuatnya lebih sulit untuk mengetahui Anda belum memasukkan salah ketik apa pun, tetapi pengetikan (secara membabi buta) fgEntersudah mencukupi (kecuali Anda memiliki banyak pekerjaan dan pekerjaan yang dimaksud bukan yang paling baru, dalam hal ini Anda memang membutuhkan deskriptor pekerjaan) ).

Jika Anda perlu menemukan deskriptor pekerjaan, gunakan terminal lain untuk mengirimkan STOPsinyal melalui metode non-interaktif di atas. Ini akan membebaskan layar Anda (mungkin menekan Enterbeberapa kali atau menjalankan clearatau Ctrl+ L) sehingga Anda kemudian dapat menjalankan jobsuntuk menemukan deskriptor pekerjaan dan kemudian jalankan di fg %Nmana Nnomor itu.


Satu-satunya masalah dengan menghentikan dan melanjutkan proses adalah bahwa jika Anda membuat koneksi ke beberapa program lain (seperti RabbitMQ misalnya), koneksi akan hilang ketika Anda melanjutkan.
Nav

@Nav - Itu karena Anda tidak menjalankannya tanpa kepala. Dalam bash dan zsh, saya percaya Anda hanya perlu menyangkal proses latar belakang. Saya lebih suka menjalankan tugas-tugas seperti itu dengan nohup atau terminal multiplexer seperti layar atau tmux . Anda tidak dapat mengambil proses nohup (seperti halnya Anda tidak dapat melanjutkan proses berlatar belakang dari koneksi terpisah), tetapi Anda dapat terhubung ke multiplexer.
Adam Katz

Itu adalah proses latar belakang. Saya telah menutup terminal dan kemudian login ke server dari terminal lain.
Nav

Ya, Anda tidak dapat melanjutkan proses dari shell lain kecuali jika diluncurkan dengan itu dalam pikiran. Saya merekomendasikan layar atau tmux untuk itu.
Adam Katz

Saya percaya bahwa jika Anda mengirim CONTsinyal ke suatu proses (pekerjaan / pipa) berhenti dengan Ctrl + Z, itu akan dilanjutkan di latar belakang, bahkan jika Anda belum bgmelakukannya.
G-Man

10

Ketik fguntuk membawanya ke latar depan.


Terima kasih! Proses menghasilkan ke stderr, jadi bagaimana saya akan mengeluarkan perintah fg <jobid>saat proses menghasilkan ke terminal?
Tim

1
  1. daftar pekerjaan dengan jobsperintah
  2. Bawa pekerjaan target Anda ke garis depan dengan fg; misalnya: fg %4
  3. Hit CTRL Zuntuk menunda
  4. Untuk mulai menjalankannya di latar belakang, gunakan bg; misalnya:bg %4

0

Mengakhiri proses dapat dilakukan dengan beberapa cara berbeda. Seringkali, dari perintah berbasis konsol, mengirim Ctrlckeystroke (karakter interupsi default) akan keluar dari perintah. Ini bekerja ketika proses sedang berjalan dalam mode foreground.

Jika suatu proses sedang berjalan dalam mode latar belakang maka pertama-tama Anda harus mendapatkan ID Pekerjaan menggunakan psperintah dan setelah itu Anda dapat menggunakan perintah kill untuk mematikan proses sebagai berikut:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Di sini killperintah akan menghentikan first_oneproses. Jika suatu proses mengabaikan killperintah biasa , Anda dapat menggunakan kill -9diikuti oleh ID proses sebagai berikut:

$kill -9 6738
Terminated

1
Meskipun ini benar, itu tidak menjawab pertanyaan ...
jasonwryan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.