Lệnh shell không đồng bộ


100

Tôi đang cố gắng sử dụng tập lệnh shell để bắt đầu một lệnh. Tôi không quan tâm nếu / khi nào / như thế nào / tại sao nó kết thúc. Tôi muốn quá trình bắt đầu và chạy, nhưng tôi muốn có thể quay lại shell của mình ngay lập tức ...


2
Liên quan, hãy xem Sự khác biệt giữa nohup, disown và & trên Unix và Linux Stack Exchange.
jww

1
Đối với những người tìm kiếm một sâu sắc hơn câu trả lời mà nói về sự khác nhau giữa nohup, &disown , bấm vào đây để cuộn để câu trả lời thứ tư .
noɥʇʎԀʎzɐɹƆ

Câu trả lời:


116

Bạn chỉ có thể chạy tập lệnh trong nền:

$ myscript &

Lưu ý rằng điều này khác với việc đưa vào &bên trong tập lệnh của bạn, điều này có thể sẽ không làm được những gì bạn muốn.


1
Tôi biết mọi chuyện sẽ trở nên dễ dàng, cảm ơn rất nhiều ... Linux không phải là thứ của tôi, nhưng tôi đang cố gắng tăng tốc ... Btw, liệu điều này có hoạt động khi kết hợp với nohup không?
LorenVS

2
Sự khác biệt giữa việc đặt & vào dòng lệnh và đưa nó vào tập lệnh là gì? Tôi không biết rằng chúng khác nhau.
Jacob Sharf

8
@JacobSharf, hãy thử và bạn sẽ thấy. Nếu &có bên trong tập lệnh và bạn không có wait, lệnh nền sẽ bị hủy khi tập lệnh thoát.
Carl Norum

Oh. Điều đó giải thích rất nhiều. Gần đây tôi đã nhận thấy một số hiệu ứng sẽ gây ra bởi điều đó. Googling nó thực sự dẫn tôi đến trang này. Cảm ơn
Jacob Sharf

Nếu myscriptsửa đổi môi trường đầu cuối, ví dụ: nó là một lệnh khởi tạo đầu cuối không cần thiết ngay lập tức và có thể bị trì hoãn, nó vẫn sẽ sửa đổi môi trường đầu cuối chứ?
noɥʇʎԀʎzɐɹƆ

58

Mọi người chỉ quên disownthôi. Vì vậy, đây là một bản tóm tắt:

  • & đặt công việc trong nền.

    • Làm cho nó chặn khi cố gắng đọc đầu vào và
    • Làm cho vỏ không phải đợi hoàn thành.
  • disown loại bỏ quá trình khỏi điều khiển công việc của trình bao, nhưng nó vẫn để nó kết nối với thiết bị đầu cuối.

    • Một trong những kết quả là trình bao sẽ không gửi nó a SIGHUP(Nếu trình bao nhận được a SIGHUP, nó cũng gửi a SIGHUPđến tiến trình, điều này thường khiến quá trình kết thúc).
    • Và rõ ràng, nó chỉ có thể được áp dụng cho các công việc nền (vì bạn không thể nhập nó khi một công việc nền trước đang chạy).
  • nohupngắt kết nối quá trình khỏi thiết bị đầu cuối, chuyển hướng đầu ra của nó đến nohup.outvà bảo vệ nó khỏi SIGHUP.

    • Quá trình sẽ không nhận được bất kỳ thư nào được gửi SIGHUP.
    • Nó hoàn toàn độc lập với kiểm soát công việc và về nguyên tắc cũng có thể được sử dụng cho các công việc tiền cảnh (mặc dù điều đó không hữu ích lắm).
    • Thường được sử dụng với &(như một công việc nền).

Tôi không thể tìm thấy disowntrên Debian hoặc OS X. Tôi đã nghĩ đó là một chương trình, nhưng dường như tôi đã nhầm. Nó là gì?
jww


6
Đây là câu trả lời tốt nhất. Toàn diện nhất.
noɥʇʎԀʎzɐɹƆ

3
Chắc chắn câu trả lời tốt nhất, không biết up tại sao rất ít
HeberLZ

1
@VladGanshin No.
Ani Menon

39
nohup cmd

không treo máy khi bạn đóng thiết bị đầu cuối. đầu ra theo mặc định là nohup.out

Bạn có thể kết hợp điều này với nền,

nohup cmd &

và loại bỏ đầu ra,

nohup cmd > /dev/null 2>&1 &

bạn cũng có thể disownmột lệnh. gõ cmd, Ctrl-Z, bg,disown


2
Thật tuyệt, thật điên rồ khi mọi thứ kết hợp với nhau, tôi nghĩ rằng thứ tự sẽ đến với tôi lúc đầu, nhưng tôi cho rằng bạn có thể ghi nhớ nó (những gì bạn đã viết hoặc "nohup cmd &> / dev / null 2> & 1" :))
LorenVS

Tôi tình cờ gặp điều này tối nay. Tôi đã chiến đấu với một kịch bản shell trong 2 ngày và gợi ý này đã giúp mọi thứ hoạt động. Xin cảm ơn mucho!
JD Dài

Tuyệt vời, điều này rất hữu ích. Khi chạy ở chế độ nền, bạn có thể kiểm tra đầu ra của lệnh thỉnh thoảng sử dụng tail nohup.out, điều này sẽ hiển thị 10 dòng cuối cùng của đầu ra lệnh. Tôi sử dụng nó cho các công việc sao lưu rsync để xem nó hiện đang ở tệp nào.
Martin Hansen

Điều gì sẽ xảy ra nếu tôi làm điều này, nhưng muốn dừng quá trình nền?
Stephan Bijzitter

Vỏ in một mã định danh công việc khi bạn bắt đầu một công việc chính xác cho mục đích này. Bạn có thể xem các công việc đang chạy của mình bất kỳ lúc nào với jobs.
tripleee

26

Ngoài ra, sau khi chương trình đang chạy, bạn có thể nhấn Ctrl-Z để dừng chương trình của bạn và sau đó nhập

bg

đặt chương trình đã dừng cuối cùng của bạn ở chế độ nền. (Hữu ích nếu bạn bắt đầu một cái gì đó mà không có '&' và vẫn muốn nó ở backgroung mà không cần khởi động lại nó)


2
Cảm ơn, đó là một mẹo nhỏ thú vị ... Bắt đầu thực sự đánh giá cao một số tính tốt của vỏ ...
LorenVS

3

screen -m -d $command$bắt đầu lệnh trong một phiên riêng biệt. Bạn có thể sử dụng screen -rđể đính kèm vào phiên bắt đầu. Nó là một công cụ tuyệt vời, cực kỳ hữu ích cho các phiên làm việc từ xa. Đọc thêm tại man screen.


@LadenkovVladislav Tôi 95% chắc chắn rằng bạn có thể cài đặt màn hình trên RedHat. Tôi có trên CentOS.
BuvinJ

Trên Ubuntu, tôi muốn mô phỏng lệnh Windows / batch "start". Tức là khởi chạy không đồng bộ chương trình nền trước (gui) và tiếp tục thông qua tập lệnh shell. Điều này thực hiện chính xác điều đó.
BuvinJ
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.