Chạy một lệnh mà không làm tôi chờ đợi


145

Trên CLI, đôi khi một lệnh tôi gõ mất một lúc để hoàn thành và đôi khi tôi biết khi nào điều đó sắp xảy ra. Tôi hơi bối rối về "nền" và như vậy trong Linux.

Cách phổ biến nhất (hoặc thân thiện với người dùng) khi nói với CLI rằng tôi không muốn chờ đợi, xin vui lòng trả lại cho tôi lời nhắc ngay lập tức. Và nếu nó có thể cho tôi một thanh tiến trình hoặc chỉ là spinner bận rộn, điều đó sẽ rất tuyệt!


3
Xem thêm Làm thế nào để bạn gửi các ứng dụng dòng lệnh trực tiếp đến nền? nếu bạn đã bắt đầu lệnh và muốn gửi nó đến nền.
Gilles

Câu trả lời:


153

Trước khi chạy lệnh, bạn có thể nối &vào dòng lệnh để chạy trong nền:

long-running-command &

Sau khi bắt đầu một lệnh, bạn có thể nhấn CtrlZđể tạm dừng nó, và sau đó bgđể đặt nó trong nền:

long-running-command
[Ctrl+Z]
bg

Tôi đã sử dụng lệnh "find ~ / a.java &" nhưng tôi không đi vào nền? Ngoài ra, tôi đã thử cmd + z (cho mac) .... nó không hoạt động
Abhimanyu Aryan

1
@AbhimanyuAryan, có thể bạn muốn gỡ lỗi find ...lệnh của bạn trước, sau đó chạy nó trong nền. Trong trường hợp này, bạn đã bỏ lỡ -nametùy chọn.
Alexis Wilke

113

Đây là mục yêu thích của tất cả vì ngoài việc gửi quy trình vào nền, bạn không phải lo lắng về việc xuất văn bản làm bẩn thiết bị đầu cuối của bạn:

nohup command &

Điều này không chỉ chạy tiến trình ở chế độ nền, mà còn tạo ra một nhật ký (được gọi nohup.outtrong thư mục hiện tại, nếu không thể, thư mục chính của bạn) và nếu bạn đóng / đăng xuất lớp vỏ hiện tại, quy trình sẽ không bị giết bằng cách ngăn chặn việc xử lý con nhận được tín hiệu cha mẹ khi bị giết (tức là đăng xuất, bằng SIGHUP cho cha mẹ hoặc đóng vỏ hiện tại).

Có một cách gọi khác disownnhưng đó đúng hơn là một phần mở rộng của các câu trả lời khác chứ không phải là một phương thức:

command & # our program is in background
disown # now it detached itself of the shell, you can do whatever you want

Các lệnh này không cho phép bạn phục hồi dễ dàng các đầu ra của quá trình trừ khi bạn sử dụng một cách hackish để hoàn thành nó.


4
Sysadmin kể từ '95. Chưa bao giờ nghe nói về sự thất vọng cho đến ngày hôm nay, cảm ơn! Nó không hoạt động với mọi shell mặc dù (bash, zsh, tcsh. Tcsh không hoạt động).
yoonix

Sử dụng nohuptrong một vỏ kiểm soát công việc là ngớ ngẩn. Vỏ hiện đại không gửi HUPđến các quá trình nền. Chuyển hướng đến một tên tệp duy nhất là một cái giá nhỏ phải trả.
gà con

@chicks trường hợp sử dụng ở đây là để ngăn chặn thiết bị lỗi chuẩn và thiết bị xuất chuẩn gây ô nhiễm thiết bị đầu cuối với điểm cộng là nó tự động tạo một tệp nhật ký.
Braiam

1
command > file.log 2>&1 & disowndài hơn một chút nohup command &nhưng tôi đoán đó là những gì @chicks đã gợi ý.
joeytwiddle

31

Đây có lẽ là những gì bạn muốn

my_command > output.log 2>&1 &

điều này sẽ bắt đầu lệnh của bạn, chuyển hướng cả thiết bị xuất chuẩn và thiết bị xuất chuẩn sang một số output.logthứ mà bạn có thể chỉ định. Nếu bạn không quan tâm đến việc lưu trữ đầu ra - bạn có thể sử dụng /dev/nullthay vì một tệp thực tế.

&sẽ thực thi lệnh trong nền để bạn có thể tiếp tục nhập lệnh trong khi nó đang chạy. 2>&1chuyển hướng stderr đến stdout để tất cả đầu ra được bắt.

Ngoài ra, khi bạn chạy một lệnh như thế này, bạn sẽ nhận được xác nhận từ kernel tương tự như sau: [2] 1234 Điều này có nghĩa là quá trình của bạn đang chạy trong nền và id của nó là 1234, vì vậy bạn có thể giết nó sau nếu muốnkill -9 1234


2
cảm ơn bạn, 2>&1rất quan trọng vì lệnh có thể thất bại và thử nó xuất ra lỗi trong một số trường hợp!
ericn

1
Điều này làm việc khi câu trả lời trên không cảm ơn.
Domagoj

9

Nhìn vào màn hình hoặc tmux . Một ví dụ với tmux:

$ tmux new -d 'longrunningcommand'

Trong khi các câu trả lời khác sử dụng '&' cho nền sẽ hoạt động, bạn phải chuyển hướng thiết bị xuất chuẩn (và thiết bị xuất chuẩn!). Không làm điều đó, đầu ra sẽ đi thẳng vào vỏ của bạn, trộn với bất kỳ đầu ra nào khác mà bạn có thể có.

Bối cảnh cũng sẽ thất bại nếu bạn đang chạy một lệnh dài và đăng xuất hoặc bị ngắt kết nối. Hệ thống sẽ giết chết công việc của bạn.

Nếu bạn không quen thuộc với màn hình hoặc tmux, về cơ bản chúng cho phép bạn tách hoàn toàn khỏi vỏ của bạn. Thay vì làm nền chương trình của bạn, bạn nền toàn bộ vỏ. Sau đó, bạn có thể chuyển về nó sau, thậm chí từ một máy tính khác. Cả hai đều có rất nhiều tính năng mà bạn có thể hoặc không thể thấy hữu ích ngoài trường hợp sử dụng này.

Màn hình là chương trình cũ đã thử và đúng; tmux trẻ hơn nhiều nhưng đã học được từ quá khứ của màn hình.


Câu trả lời này bỏ lỡ một câu trả lời thực tế và nghe giống như một RTFM.
orgeki

5

(Để hoàn thiện-- đã trả lời rồi :) Bạn đặt một lệnh dưới nền bằng cách thêm &sau lệnh:

long_command with arguments > redirection &

Tôi đang thêm câu trả lời này để giải quyết phần khác của câu hỏi của bạn:

Không có tương đương thực sự của công cụ quay vòng để hiển thị các lệnh nền đang thực hiện, nhưng bạn có thể thấy trạng thái của các lệnh nền bằng cách nhập jobshoặc jobs -l. Nó sẽ hiển thị cho bạn các lệnh nền của bạn và liệu chúng có đang chạy hay không, dừng qua tín hiệu (ví dụ: với ^Z) hoặc đôi khi dừng vì chúng đang chờ đầu vào tương tác từ bạn.


long_command with arguments &> redirection &để chuyển hướng stderrquá
Ice-Blaze

3

Bạn có thể chạy một chương trình trong nền bằng cách sử dụng &. Ví dụ: nếu bạn muốn chạy yum install XyZchẳng hạn, bạn có thể chạy:

yum install XyZ &

stdoutthể chuyển hướng hoặc đầu ra từ chương trình bằng cách >ghi đè lên một tệp hoặc >>để thêm vào một tệp. Ví dụ: nếu bạn muốn đăng nhập yumvào một tệp yum.log:

yum install XyZ > yum.log &

Hoặc, nếu bạn muốn thêm đầu ra vào một tệp hiện có log:

yum install XyZ >> log &

Lỗi được in stderrvà không stdout, và có thể được chuyển hướng đến một tệp theo cùng một cách, nhưng sử dụng 2>:

yum install XyZ 2> errors
yum install XyZ 2>> errors

Nếu bạn muốn chuyển hướng cả hai stderrstdout, bạn có thể sử dụng &>:

yum install XyZ &> output
yum install XyZ &>> output

2

Bạn có thể chạy một lệnh trong nền chỉ bằng cách đặt &dấu sau nó.

Ví dụ:

areallylong_command &

sẽ chạy nó trong nền.

Bạn có thể chuyển hướng stdout / stderr sang các tệp thích hợp để chúng không xuất hiện trên thiết bị đầu cuối của bạn trong khi bạn đang làm gì đó.

Xem phần này để biết thêm: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html


0

Hãy thử sử dụng lệnh 'screen' trước khi bạn bắt đầu tác vụ chạy dài của mình, sau đó khi bạn tách ra, bạn có thể gắn lại với 'screen -r -d' bất cứ khi nào bạn cần làm lại. Tôi thấy rằng khi sử dụng thiết bị đầu cuối qua ssh hoặc các kết nối mạng khác, đôi khi chúng có thể bị hỏng do kết nối xấu đến máy chủ. chạy nó trong 'màn hình' sẽ khắc phục vấn đề này.

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.