Làm cách nào tôi có thể chạy nhiều lệnh có & trong một dòng lệnh?


12

Tôi đã gặp phải một vấn đề đau đầu.

Tôi muốn thực thi các lệnh mulitple trong nền, vì vậy tôi muốn bắt đầu chúng trong bash từng cái một. Thật dễ dàng để bắt đầu một lệnh trong linux shell trong nền, giống như thế này:

myCommand &

Thật dễ dàng để bắt đầu nhiều lệnh, giống như thế này:

myCommand1 && myCommand2

hoặc là

myCommand1 ; myCommand2

Nhưng nếu tôi muốn chạy nhiều lệnh trong nền, tôi đã thử định dạng lệnh sau, nhưng không thành công:

myCommand1 & && myCommand2 &

hoặc là

myCommand1 & ; myCommand2 &

Cả hai định dạng đều thất bại. Làm thế nào tôi có thể chạy nhiều lệnh có &trong một dòng lệnh?


2
Đặt chúng vào một tập lệnh và chạy tập lệnh ở chế độ nền
Panther



Panther, có vẻ như việc sử dụng () có thể giúp khắc phục vấn đề này dễ dàng hơn nhiều so với sử dụng tập lệnh. Trước tiên, hãy thử sử dụng đầy đủ các tính năng được cung cấp bởi trình bao, thay vì tự mình sáng tác những gì chúng ta muốn. Nhưng tất nhiên, sử dụng script cũng có thể khắc phục vấn đề này. Dẫu sao cũng xin cảm ơn.
Đồng hồ NGÀY

Điều gì sẽ xảy ra nếu tôi muốn chạy 'đuôi -F <file1 >> <file2>' theo sau là 'jobs -l', tiếp theo là 'disown -h% 1'
akskap

Câu trả lời:


24

Sử dụng ().

Nếu bạn muốn chạy chúng tuần tự:

(myCommand1; myCommand2) &

hoặc là

(myCommand1 &) && (myCommand2 &)

Nếu bạn muốn chúng chạy song song:

myCommand1 & myCommand2 &

Trong bash, bạn cũng có thể sử dụng cái này (khoảng trắng phía sau {và; là bắt buộc):

{ myCommand1 && myCommand2; } &

3
(myCommand1 &) && (myCommand2 &)sẽ chạy myCommand2ngay cả khi myCommand1thất bại.
terdon

() có thể giúp bash phân biệt & & &. Vì vậy, chỉ sử dụng () để phân tách đơn vị thực thi khi chúng tôi muốn sử dụng & & & togather.
Đồng hồ NGÀY

16

Tôi cho rằng bạn muốn điều này:

myCommand1 & myCommand2 &

Điều này bắt đầu myCommand1và gửi nó đến nền khi nó được theo sau bởi dấu và sau đó ngay lập tức bắt đầu myCommand2và cũng gửi nó đến nền, do đó giải phóng lại vỏ.

Danh sách

Để hiểu rõ hơn bạn có thể thay thế đường ống bằng lệnh ở đây.

Danh sách là một chuỗi gồm một hoặc nhiều đường ống được phân tách bởi một trong các toán tử ; , & , && , hoặc || và tùy ý chấm dứt bởi một trong số ; , & , hoặc .

Nếu một lệnh bị chấm dứt bởi toán tử điều khiển & , shell sẽ thực thi lệnh trong nền trong một lớp con. Shell không chờ lệnh kết thúc và trạng thái trả về là 0. Các lệnh được phân tách bằng a ; được thực hiện tuần tự; Shell chờ lần lượt từng lệnh kết thúc. Trạng thái trả về là trạng thái thoát của lệnh cuối cùng được thực thi.

Danh sách AND và OR là các chuỗi của một hoặc nhiều đường ống được phân tách bằng &&|| toán tử điều khiển, tương ứng.
Nguồn:man bash

Hãy chia nó thành các ví dụ. Bạn có thể tạo danh sách bằng cách kết hợp các lệnh và tách chúng với một trong các cách sau ; & && ||::

command1 ; command2  # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2  # runs simultaneously

Bạn có thể chấm dứt danh sách với một trong những điều sau : ; & <newline>.
Thông thường bạn thực hiện một lệnh hoặc một danh sách bằng cách nhấn Enter, bằng <newline>. Dấu chấm phẩy ;phục vụ cho cùng một mục đích, đặc biệt là trong các tập lệnh. Ampersand &tuy nhiên bắt đầu (các) lệnh trong một lớp con trong nền, ngay lập tức giải phóng shell.

Bạn có thể sử dụng ()dấu ngoặc tròn hoặc xoăn {}để thêm danh sách nhóm, sự khác biệt là dấu ngoặc tròn sinh ra một khung con và các dấu ngoặc nhọn không. Dấu ngoặc nhọn cần một khoảng trắng sau dấu đầu tiên và dấu chấm phẩy hoặc dòng mới trước dấu ngoặc đóng. Ví dụ:

# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) & 
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &

Điều này có thể trở nên khá phức tạp, nếu bạn không chắc chắn sử dụng truefalseđể kiểm tra xem liệu công trình có hoạt động như mong đợi hay không:

$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2

Kiểm soát công việc

Các jobslệnh hiển thị một danh sách các công việc nền đang chạy hoặc gần đây đã được hoàn thành trong vỏ hiện hành. Có một số phím tắt và lệnh để điều khiển công việc:

  • Ctrl+ ZLoại các đình chỉ nhân vật mà làm cho quá trình hiện đang chạy trong foreground được dừng lại, nó không phải là chấm dứt, nhưng phần còn lại trong jobsdanh sách
  • Ctrl+ YLoại các trì hoãn đình chỉ nhân vật mà làm cho quá trình hiện đang chạy trong foreground được dừng lại khi nó cố gắng để đọc đầu vào từ thiết bị đầu cuối
  • fg= %đưa một quy trình vào tiền cảnh bắt đầu nó nếu cần thiết, bạn có thể chỉ định quy trình như sau:

     %       # last process in the jobs list
     %1      # 1st process in the jobs list
     %abc    # process beginning with the string “abc”
     %?abc   # process containing the string “abc” anywhere
  • bg= %&mất một quá trình vào nền bắt đầu nó nếu cần thiết:

     %&      # last process in the jobs list
     %1&     # 1st process in the jobs list
     %abc&   # process beginning with the string “abc”
     %?abc&  # process containing the string “abc” anywhere
  • wait chờ cho một quá trình nền kết thúc và trả về trạng thái chấm dứt của nó:

     wait %1 # 1st process in the jobs list

    Hãy tưởng tượng bạn đã bắt đầu một quá trình dài ( jobstiết lộ đó là số 3) và sau đó nhận ra rằng bạn muốn máy tính bị treo khi kết thúc, cộng với echomột thông báo nếu quá trình không thành công:

     wait %3 || echo failed ; systemctl suspend

Nhưng điều quan trọng là phải cẩn thận với && nó phụ thuộc vào những gì lệnh trả về , vì vậy chúng ta cần chắc chắn rằng bất cứ điều gì chúng ta gọi thực sự trả về một cái gì đó bash đều coi là giá trị trung thực ..?
mathreadler

@mathreadler Trừ khi bạn nói về một số tập lệnh người dùng được tạo ra kém, giá trị thoát được xác định rất rõ (xem man bash) và được sử dụng rộng rãi chính xác như AFAIK dự định - Tôi chưa bao giờ trải nghiệm điều gì kỳ lạ.
tráng miệng

chính xác, người ta nên cẩn thận về các tập lệnh người dùng được thực hiện kém. Chúng tồn tại và có thể là một nỗi đau để tìm ra những lỗi như vậy. Askubfox không cho phép tôi "@ tráng miệng" bạn.
mathreadler

Ah được rồi, điều đó có ý nghĩa khi bạn đề cập đến nó.
mathreadler
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.