Quá trình trong nền mà không có & &


24

Giả sử bạn đã bắt đầu một ứng dụng mới trong Linux (như trình soạn thảo văn bản, v.v.), nhưng bạn đã quên sử dụng ứng dụng & &. Bạn sẽ sử dụng lệnh nào để làm cho quá trình đó chạy trong nền, trong khi KHÔNG phải ĐÓNG ứng dụng đó? Theo cách này, bạn có thể có cả hai quy trình mở và làm việc riêng biệt (ví dụ: thiết bị đầu cuối dòng lệnh bạn đã sử dụng để tạo quy trình và quy trình như trình soạn thảo văn bản vẫn đang chạy.?


Về mặt kỹ thuật không nhưng có lẽ tmuxcung cấp các chức năng như mong muốn trong câu hỏi của bạn.
mkc

1
Đừng bỏ qua cách thay thế đơn giản là mở vỏ khác khi có thể.
jpmc26

Câu trả lời:


43

Trong cửa sổ terminal, bạn thường gõ Control+ Zđể "tạm dừng" quá trình và sau đó sử dụng bglệnh để "nền" nó.

ví dụ với lệnh ngủ

$ /bin/sleep 1000
^Z[1] + Stopped                  /bin/sleep 1000
$ bg
[1]     /bin/sleep 1000&
$ jobs
[1] +  Running                 /bin/sleep 1000
$ 

Chúng ta có thể thấy quá trình đang chạy và tôi vẫn có dòng lệnh của mình.


5
Thật thú vị khi thêm rằng quá trình có thể được đưa trở lại nền trước bằng fglệnh, lấy id công việc (được chỉ định trong ngoặc, 1trong trường hợp này) làm tham số. Nó không cụ thể đối với việc sử dụng bgvà có thể được thực hiện trên các quy trình được khởi chạy cùng &.
Aaron

14

Ctrl+ Zlà cách để làm điều đó, nhưng chỉ để hoàn thiện: câu hỏi yêu cầu "lệnh" và đó sẽ là (từ một thiết bị đầu cuối khác):

kill -STOP pid_of_the_running_applications

và dĩ nhiên rồi

bg

từ thiết bị đầu cuối ứng dụng.


6
kil -STOP, và sau đó giết -CONT
Michel Billaud

10

Trong Bash:

Ctrl+ Zvà sau đó bg.

Bây giờ chạy jobsvà xem kết quả.


2
@grooveplex Tomas đã trả lời trước, vì vậy sẽ phù hợp hơn khi bình luận bên dưới câu trả lời của Stephen, về cơ bản câu trả lời của anh ấy là tomas` với một số chi tiết hơn.
Anthon

2
Chúng tôi thực sự trả lời đồng thời. Không có gì đáng ngạc nhiên khi cả hai chúng tôi đều nói điều tương tự vì đó là câu trả lời rõ ràng :-) Cả hai chúng tôi đều không sao chép cái kia. Câu trả lời của tôi đã đến ngay sau Thomas 'vì tôi đã dành thêm thời gian để tạo và định dạng ví dụ.
Stephen Harris

1
Và tôi nói nó ở Bash, nên chúng không giống nhau.
Tomasz

1
Heh, có một điểm tiềm năng ở đó. Nó đòi hỏi phải có vỏ để kiểm soát công việc. Một số máy đầu tiên tôi làm việc (dựa trên SVr2) không có trong đó /bin/shvà vì vậy điều này sẽ không hoạt động :-)
Stephen Harris

1

Là một biện pháp phòng ngừa cho sự bất tiện khi phải nhấn CTRL- z, bạn có thể tạo một tập lệnh bao bọc cho trình soạn thảo để chạy trình soạn thảo của bạn trong nền. Bằng cách này, bạn sẽ không cần phải nhớ để bắt đầu nó trong nền một cách rõ ràng:

    #!/bin/sh

    EDITOR="emacs" # or whatever

    if [ -z "${DISPLAY}" ]; then
      ${EDITOR} "$@"
    else
      ${EDITOR} "$@" &
    fi

Ở trên trước tiên chúng tôi cố gắng xác định xem bạn có máy chủ X khả dụng không và chỉ sau đó chạy trình chỉnh sửa ở chế độ nền (nếu không, nhiều trình soạn thảo Unix sẽ sử dụng thiết bị đầu cuối của bạn và bạn không muốn chạy trình chỉnh sửa làm tiến trình nền trong trường hợp này) . Nó sẽ chuyển tất cả các đối số cho trình soạn thảo của bạn về nguyên văn lựa chọn ( "$@") giống như bạn đã cung cấp cho tập lệnh trình bao bọc.

Đối với lệnh bạn đang thiếu ... Theo thử nghiệm cơ bản của tôi, đối với các chương trình GUI không liên quan đến thiết bị đầu cuối, nó có thể đơn giản như lần gửi đầu tiên SIGSTOPvà sau đó SIGCONTđến quy trình nền trước (sử dụng killlệnh nếu bạn sử dụng tập lệnh shell để thực hiện điều này) . Tất nhiên, bạn sẽ cần phải chạy nó trong một cửa sổ / tab thiết bị đầu cuối khác, và khó khăn sẽ là thuận tiện và theo cách chung chung để tìm ra PID mà bạn muốn gửi tín hiệu của mình. Theo mặc định, bạn có thể gửi hai tín hiệu cho tất cả các quy trình của tên đã cho (mặc định cho trình soạn thảo yêu thích của bạn và cũng cho phép sử dụng PID làm đối số):

    #!/bin/sh

    EDITOR=emacs # whatever

    stop_cont_prog()
    {
      case "$1" in
        # begin with number is considered PID - this is not good 
        # enough to be taken seriously...
        [1-9]*) kill -SIGSTOP "$1"; kill -SIGCONT "$2";;
        *)      killall -SIGSTOP "$1"; killall -SIGCONT "$2";;
      esac
    }

    if [ -n "$1" ]; then
      for prog in "$@"; do stop_cont_prog "$1"; done
    else  
      stop_cont_prog "${EDITOR}"
    fi

Phương pháp này chính xác đã cho tôi các tab thiết bị đầu cuối của tôi cho tôi sau khi chạy (một số) emacslệnh trong nền. Nhưng quá trình emacs chạy trong thiết bị đầu cuối không được khôi phục đúng cách do điều khiển công việc shell hoặc nhầm lẫn cài đặt thiết bị đầu cuối. Vì vậy, phương pháp này sẽ được hưởng lợi từ một số tinh vi.

Đây SIGSTOPchính xác là những gì được gửi đến quá trình tiền cảnh khi bạn nhấn (theo mặc định chung) CTRL- z. Tham khảo stty -ađầu ra

$ stty -a
speed 38400 baud; rows 50; columns 200; line = 0;
intr = ^C; [...] start = ^Q; stop = ^S; susp = ^Z; [...]
[...]

(viết tắt đầu ra) và sttytrang hướng dẫn:

   susp CHAR
          CHAR will send a terminal stop signal

Quá trình dừng sử dụng SIGSTOPtín hiệu có thể được khởi động lại bằng cách gửi SIGCONT. Thông thường, logic điều khiển công việc shell sẽ gửi SIGCONTvà xử lý các thao tác cần thiết khác liên quan đến fgbgcác lệnh mà chúng ta bỏ qua.

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.