Làm thế nào để tôi rẽ nhánh một quá trình không chết khi thoát khỏi vỏ?


31

Nếu tôi chạy emacs từ shell:

$ emacs foo &

và sau đó giết cái vỏ đó, emacs chết.

Làm thế nào tôi có thể chạy một lệnh để nó không chết khi vỏ chết?

Tôi đã tìm thấy tài liệu tham khảo về nohup, nhưng điều đó dường như không giúp được gì:

$ nohup emacs foo &

vẫn giết chết emacs khi vỏ chết.

Câu trả lời:


13

Bạn không đề cập nếu điều này đang chạy dưới dạng ứng dụng X hoặc ứng dụng bảng điều khiển.

Nếu nó là một ứng dụng giao diện điều khiển, tất nhiên nó cần phải đóng lại. Bạn đã loại bỏ đầu vào / đầu ra của nó, về mặt kỹ thuật hơn (giả) nó đã được bật. Rất có thể đây là ý của bạn, vì vậy hãy giả sử bạn đang nói về một ứng dụng X.

nohupnên làm việc, không chắc tại sao nó không. Khi shell đóng, nó sẽ gửi SIGHUPđến tất cả các quy trình trong nhóm quy trình của nó. nohup nói lệnh bỏ qua SIGHUP.

Bạn cũng có thể thử setsid, ngắt kết nối tiến trình khỏi nhóm quy trình

alias emacs='setsid emacs'

Hoặc thêm disownsau&


Ah, công việc tuyệt vời. Xin lỗi về việc không rõ ràng. Có, tôi đang đề cập đến các ứng dụng X không thực sự chạy trong trình bao. Về cơ bản, tôi muốn khởi động emacs (hoặc bất kỳ quá trình nào khác) từ vỏ, nhưng tôi không muốn nó theo bất kỳ cách nào gắn liền với vỏ. Tôi chỉ bắt đầu ở đó cho thuận tiện.
sligocki

41

Phương pháp đáng tin cậy nhất dường như là:

(setsid emacs &)

Điều này sử dụng ( &)để rẽ nhánh, và setsidtách ra khỏi tty kiểm soát.

Bạn có thể đặt cái này trong hàm shell:

fork() { (setsid "$@" &); }

fork emacs

Các khả năng là:

  • Lệnh disowndựng sẵn:

    emacs &
    disown $!
    

    &đóng vai trò là dấu phân cách lệnh và disownsẽ mặc định cho công việc gần đây nhất, vì vậy điều này có thể được rút ngắn thành:

    emacs & disown
    
  • Đôi- fork():

    (emacs &)
    

    Các lệnh bên trong dấu ngoặc đơn ( )được chạy trong một quy trình shell riêng.

  • setsid, như được đề xuất bởi Rich, có thể là lựa chọn tốt nhất, vì nó hủy bỏ TTY kiểm soát của quy trình bằng cách tạo một phiên mới :

    setsid emacs
    

    Tuy nhiên, điều này cũng hơi khó đoán - nó sẽ chỉ fork()làm nền nếu đó là người lãnh đạo của một nhóm quy trình (điều này sẽ không xảy ra nếu setsidđược sử dụng trong một shtập lệnh, chẳng hạn, trong những lần như vậy, nó sẽ chỉ trở nên chống lại Ctrl- C.)


Tuyệt quá! tất cả những công việc này cho tôi Rất vui khi có thêm một số công cụ trong kho vũ khí của tôi.
sligocki

Hừm ... sẽ (exec emacs)làm việc chứ?
Hello71

@ Hi vọng: Nó sẽ không khác gì chỉ (emacs). Nếu subshell được đưa ra một lệnh duy nhất, execthì hàm ý đó, ít nhất là trong trường hợp bash. Áp dụng tương tự cho bash -c 'foo'so với bash -c 'exec foo'. (Tuy nhiên, lưu ý rằng bản thân emacs có thể tách ra khỏi thiết bị đầu cuối; gvim, ví dụ, thực hiện việc này. Tốt hơn là nên thử nghiệm với một chương trình có hành vi đã biết.)
grawity

Tuyệt vời để tìm hiểu về kỹ thuật hai ngã ba; cảm ơn!
Dave Abrahams

Tìm thấy điều này trong khi trolling để khắc phục một vấn đề của riêng tôi. (Setid emacs &) làm việc cho tôi. Cảm ơn cho một câu trả lời bằng văn bản.
Paulb

5

Kiểm tra cài đặt vỏ của bạn. Bạn cũng có thể thử màn hình thay vì nohup.


Màn hình cho phép bạn quay lại quá trình sau screen -rnếu bạn sử dụng Ctrl-A Ctrl-Dđể ngắt kết nối trước khi đăng xuất.
Broam

Đây là một điểm rất tốt. Tôi cần điều ngược lại, tức là từ bỏ một subshell và tiến hành các nhiệm vụ khác mà không cần chờ nó hoàn thành, nhưng screen -d -m sh -c "{do stuff } exit"có ý nghĩa hơn nhiều.
Nemo
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.