Làm cách nào để tạm dừng và đưa quy trình nền lên nền trước


167

Tôi có một quá trình ban đầu chạy ở nền trước. Tôi bị treo bởi Ctrl+ Z, và sau đó tiếp tục chạy trong nền bg <jobid>.

Tôi tự hỏi làm thế nào để đình chỉ một quá trình chạy trong nền?

Làm thế nào tôi có thể mang một quá trình nền để tiền cảnh?

Biên tập:

Quá trình xuất ra stderr, vậy tôi sẽ phát lệnh như thế nào fg <jobid>trong khi quá trình xuất ra thiết bị đầu cuối?


1
Bạn vẫn có thể gõ các lệnh trong một thiết bị đầu cuối đang phát sinh lỗi. Văn bản được phun trên STDERR không được tính là đầu vào, chỉ các khóa bạn gửi. Nó trông khó hiểu trên màn hình nhưng nó hoạt động.
Caleb

@Caleb: Ngay cả khi quá trình xuất ra thiết bị xuất chuẩn, tôi vẫn có thể gõ fg <jobid>để làm cho nó trở nên tiên phong?
Tim

@Tim: Vâng, bạn có thể.
Caleb

Câu trả lời:


216

Như Tim đã nói, gõ fgđể đưa quá trình cuối cùng trở lại nền trước.

Nếu bạn có nhiều hơn một quá trình đang chạy trong nền, hãy làm điều này:

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

fg %3để đưa vim 23quá trình trở lại tiền cảnh.

Để tạm dừng quá trình đang chạy trong nền, hãy sử dụng:

kill -STOP %job_id

Tín hiệu SIGSTOP dừng (tạm dừng) một quá trình về cơ bản giống như cách Ctrl+ Zthực hiện.

ví dụ : kill -STOP %3.

nguồn: Cách gửi tín hiệu đến các quy trình trong Linux và UnixCách quản lý các công việc nền và tiền cảnh .


23
tín hiệu 19 là SIGCONTcho tôi; Tôi sử dụng kill -STOPkill -CONTưu tiên ghi nhớ các số dù thế nào, nhưng bạn có thể kiểm tra kill -lđể tự nhắc nhở mình về các giá trị số
Vô dụng

Quá trình xuất ra stderr, vậy tôi sẽ phát lệnh như thế nào jobfg <jobid>trong khi quá trình xuất ra thiết bị đầu cuối?
Tim

1
@Tim Chỉ cần gõ lệnh như bình thường. Miễn là công việc được làm nền, nó không đọc những gì bạn gõ - vỏ của bạn là. Những gì bạn gõ có thể bị phá vỡ đối với bạn, nhưng vỏ sẽ hiểu nó tốt.
AlexWebr

@AlexWebr: Cảm ơn, nó hoạt động! (1) Công việc nền không chấp nhận bất kỳ đầu vào và đầu ra nào, bao gồm cả "Ctrl + Z", v.v., phải không? (2) Một công việc đang chạy trong nền có thể bị đình chỉ trực tiếp không? Nếu có, làm thế nào? Nếu không, trước tiên nó phải được thay đổi để chạy ở nền trước trước khi nó có thể bị treo?
Tim

2
Một công việc đang chạy trong nền có thể bị đình chỉ trực tiếp có:, kill -STOP %job_idnhư đã giải thích
Vô dụng

31

Điều này đúng với bất kỳ hệ vỏ nào có kiểm soát công việc, mà (đối với hầu hết các phần) bạn có thể được cấp trừ khi xử lý một vỏ thực sự cổ xưa. Đó là trong tiêu chuẩn POSIX , do đó, thậm chí còn dashhỗ trợ kiểm soát công việc (khi chạy tương tác hoặc với -m).

Tương tác

  • Ctrl+ zsẽ tạm dừng chương trình hiện tại
  • bgsẽ làm nền cho chương trình bị đình chỉ gần đây nhất
    (sử dụng bg %2với số công việc mà bạn có thể kiểm tra jobs)
  • fg sẽ báo trước chương trình bị đình chỉ gần đây nhất

Trong zsh, bạn có thể viết một ràng buộc khóa để chạy ngầm fgtừ dấu nhắc thông qua dấu Ctrl+ khác z:

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

Có lẽ cũng có một cách thông minh để chạy ngầm bgkhi đình chỉ, nhưng có vẻ không khôn ngoan; ít nhất là đối với tôi, phần lớn việc sử dụng Ctrl+ của tôi zlà vì Ctrl+ ckhông thoát ra được; Tôi muốn làm theo điều đó với ví dụ kill %1chứ không phải bg, và tôi chắc chắn không muốn mặc định giết người! (Logic này cũng mở rộng lý do tại sao tôi không còn sử dụng ràng buộc khóa này nữa: Nếu tôi đang gõ vào Ctrl+ zđể dừng một quá trình, điều cuối cùng tôi muốn nó làm là tiếp tục!)

Không tương tác

Nếu bạn ở trong một phiên bản shell khác (hoặc một người dùng khác, đôi khi bao gồm sudocác lệnh), bạn có thể sẽ không thể sử dụng số công việc.

Bạn vẫn có thể hành động trên một quy trình khác sau khi bạn biết ID quy trình của nó (PID). Bạn có thể nhận được PID với pgrep …, hoặc ps aux |grep …(hoặc từ cùng một vỏ jobs -l, hoặc $!) và sau đó bạn có thể chạy:

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

Nếu bạn không biết ID tiến trình và không lo lắng về việc tạm dừng các phiên bản khác của quy trình theo tên, bạn có thể truyền tín hiệu cho một trong những điều sau:

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

Một CONTtín hiệu cho một chương trình đã dừng với Ctrl+ z(chứ không phải bg'd) sẽ tiếp tục tiến trình của nó (ở nền trước), giống như khi bạn thực hiện fgnó.

Re: Lỗi tiêu chuẩn

Chỉnh sửa cho câu hỏi này hỏi về lỗi tiêu chuẩn:

Quá trình xuất ra stderr, vậy tôi sẽ phát lệnh như thế nào fg <jobid>trong khi quá trình xuất ra thiết bị đầu cuối?

Trừ khi công việc được đề cập có các thành phần được làm nền (hoặc toàn bộ công việc được tạo nền, có lẽ thông qua kill -CONT), bạn thực sự không nên thấy đầu ra trong khi nó bị treo.

Nếu nó vẫn xuất dữ liệu (có thể là đầu ra tiêu chuẩn hoặc lỗi tiêu chuẩn), nó chắc chắn sẽ làm cho thiết bị đầu cuối của bạn bị lộn xộn, nhưng tất cả đầu ra đó sẽ bị bỏ qua vì nó không phải là một phần của đầu vào của bạn. Điều này có thể làm cho khó biết bạn chưa nhập bất kỳ lỗi chính tả nào, nhưng gõ (mù) fgEntersẽ đủ (trừ khi bạn có nhiều công việc và câu hỏi không phải là gần đây nhất, trong trường hợp đó bạn thực sự sẽ cần mô tả công việc ).

Nếu bạn cần tìm mô tả công việc, hãy sử dụng một thiết bị đầu cuối khác để gửi STOPtín hiệu thông qua các phương thức không tương tác ở trên. Điều này sẽ giải phóng màn hình của bạn (có thể nhấn Entermột vài lần hoặc chạy clearhoặc Ctrl+ L) để bạn có thể chạy jobsđể tìm mô tả công việc và sau đó chạy số fg %Nđó ở đâu N.


Vấn đề duy nhất với quá trình tạm dừng và tiếp tục là nếu bạn thực hiện bất kỳ kết nối nào với một số chương trình khác (ví dụ như RabbitMQ), kết nối sẽ bị mất khi bạn tiếp tục.
Nav

@Nav - Đó là vì bạn không chạy nó không đầu. Trong bash và zsh, tôi tin rằng bạn chỉ cần từ chối một quá trình nền. Tôi thích chạy các tác vụ như vậy với nohup hoặc bộ ghép kênh đầu cuối như màn hình hoặc tmux . Bạn không thể chọn quy trình xử lý (giống như bạn không thể tiếp tục quy trình nền từ một kết nối riêng), nhưng bạn có thể kết nối với bộ ghép kênh.
Adam Katz

Đó là một quá trình nền tảng. Tôi đã đóng thiết bị đầu cuối và sau đó đăng nhập vào máy chủ từ thiết bị đầu cuối khác.
Nav

Vâng, bạn không thể tiếp tục một quá trình từ một shell khác trừ khi nó được khởi chạy với ý nghĩ đó. Tôi khuyên bạn nên màn hình hoặc tmux cho điều đó.
Adam Katz

Tôi tin rằng nếu bạn gửi CONTtín hiệu đến một quá trình (công việc / đường ống) đã dừng bằng Ctrl + Z, nó sẽ tiếp tục ở chế độ nền, ngay cả khi bạn không làm bgnhư vậy.
G-Man

10

Nhập fgđể đưa nó lên nền trước.


Cảm ơn! Quá trình xuất ra stderr, vậy tôi sẽ phát lệnh như thế nào fg <jobid>trong khi quá trình xuất ra thiết bị đầu cuối?
Tim

1
  1. liệt kê các công việc có jobslệnh
  2. Đưa công việc mục tiêu của bạn lên tiền cảnh với fg; ví dụ: fg %4
  3. Lượt CTRL Zđể đình chỉ
  4. Để bắt đầu nó chạy trong nền, sử dụng bg; ví dụ:bg %4

0

Kết thúc một quá trình có thể được thực hiện theo nhiều cách khác nhau. Thông thường, từ một lệnh dựa trên bảng điều khiển, việc gửi một Ctrlctổ hợp phím (ký tự ngắt mặc định) sẽ thoát lệnh. Điều này hoạt động khi quá trình đang chạy trong chế độ nền trước.

Nếu một tiến trình đang chạy ở chế độ nền thì trước tiên bạn cần lấy ID công việc của nó bằng pslệnh và sau đó bạn có thể sử dụng lệnh kill để giết tiến trình như sau:

$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

Ở đây killlệnh sẽ chấm dứt first_onequá trình. Nếu một quy trình bỏ qua một killlệnh thông thường , bạn có thể sử dụng kill -9theo sau bởi ID tiến trình như sau:

$kill -9 6738
Terminated

1
Trong khi điều này là đúng, nó không trả lời câu hỏi ...
jasonwryan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.