Cái nào tốt hơn: sử dụng; hoặc && để thực thi nhiều lệnh trong một dòng?


427

Trong hướng dẫn và cách làm tôi thường thấy các lệnh kết hợp. Ví dụ,

sudo apt-get update && sudo apt-get install pyrenamer

Dường như có bốn giắc nối có thể: &, &&, ||;. Mặc dù trình & kết nối rõ ràng với tôi (nó gửi một quá trình đến nền và để thiết bị đầu cuối khả dụng), nhưng không rõ sự khác biệt giữa &&;. Và tôi đã không biết ||cho đến khi bình luận của Kaya.

Các câu hỏi sau đây liên quan đến sự khác biệt giữa hai kết nối, nhưng chủ yếu là trong các ý kiến:

Vì vậy, đây là một số câu hỏi liên quan:

  1. Sự khác biệt giữa ;và là &&gì?
  2. Khi nào bạn nên sử dụng chúng tương ứng? Sẽ thật tuyệt khi thấy một số trường hợp sử dụng: nếu tôi muốn chạy một lệnh và sau đó nó tắt máy tính của tôi, tôi nên chọn trình kết nối nào?
  3. Lợi thếnguy hiểm của họ là gì? Robie Basak đề cập trong một bình luận cho câu trả lời này rằng một lệnh như thế cd /somewhere_else; rm -Rf *có thể gây ra hậu quả hủy diệt nếu phần tử đầu tiên trong chuỗi lệnh thất bại, chẳng hạn.
  4. Nếu có liên quan, họ đến từ đâu?

7
Có một trình kết nối khác mà bạn có thể không bắt gặp: ||cũng giống như &&ngoại trừ việc nó chỉ thực thi lệnh thứ hai nếu lệnh đầu tiên thoát với trạng thái khác không (không thành công).
Kaya

4
Cũng lưu ý rằng việc chạy tập lệnh của bạn set -esẽ dừng tập lệnh bị lỗi như thể tất cả các lệnh được kết nối với &&.
choroba


3
Không ai trả lời Qn 4 ... Tôi nghi ngờ hành vi của && và || được lấy cảm hứng từ ngôn ngữ lập trình C. Trong trường hợp (x && y), nếu x ước lượng thành false, toàn bộ biểu thức phải là sai để trình biên dịch có thể tối ưu hóa việc đánh giá y, trong trường hợp nó đắt tiền. Các tiêu chuẩn C và C ++ hiện đại thực sự yêu cầu tối ưu hóa này, vì vậy các chương trình có thể cho rằng y sẽ không được đánh giá một cách an toàn nếu x sai. Chẳng hạn, (ptr && ptr-> ngày> 31) sẽ không gặp sự cố ngay cả khi ptr là null. Cũng trong C, các câu kết thúc bằng; bất kể có một tuyên bố khác trên cùng một dòng hay không.
Kevin

Câu trả lời:


771

Áo choàng:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.

19
Và tất nhiên , A & B &: Chạy A ở chế độ nền, sau đó chạy B ở chế độ nền (bất kể thành công) và trả lại quyền điều khiển cho trình bao. Điều này thường hoạt động tương tự như chạy cả hai quá trình cùng một lúc.
Chuộc tội có giới hạn

4
có thể nói: chạy một nền, theo sau là b trong nền chỉ khi một công việc? (Tôi đoán &&&?)
user230910

15
@ user230910: sẽ như vậy (A && B) &.
leftaroundabout

5
Bạn có thể tham khảo tài liệu có thẩm quyền cho việc này?.
Jaime Hablutzel

@Jack Khi được thực hiện từ Cronjob, nó không hoàn toàn tuân theo quy tắc này, bạn có biết tại sao không? Đối với tệp python
CodeGuru

77

&&chỉ chạy lệnh thứ hai nếu lệnh đầu tiên thoát với trạng thái 0 (đã thành công). ;chạy cả hai lệnh, ngay cả khi lệnh đầu tiên thoát với trạng thái khác không.

Ví dụ của bạn với &&có thể được diễn giải tương đương như

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi

Cảm ơn. Tôi đã cập nhật câu hỏi để đảm bảo các câu hỏi con khác nhau có thể dễ dàng phân biệt.
don.joey

5
@Private: Bạn nên sử dụng ;nếu lệnh thứ hai không cần lệnh trước để thành công.
choroba

31

Sử dụng ;sẽ thực thi các lệnh bất kể lệnh đầu tiên có thành công hay không.

chỉ sử dụng &&lệnh thứ 2 khi lệnh đầu tiên được thực hiện thành công (trạng thái 0).

Cả hai đều được sử dụng trên quan điểm khác nhau. Giống như cho một quá trình dài hơn, nói về một cài đặt bạn cần biên dịch và cài đặt nó. bạn nên make && make install. Vì vậy, cài đặt sẽ chỉ chạy nếu makethành công.

Vì vậy, đối với các lệnh phụ thuộc, bạn nên sử dụng &&

Bring bash, hoặc các lệnh với các lệnh độc lập sử dụng ;

Vì vậy, nếu bạn muốn tắt máy tính ngay cả lần đầu tiên sử dụng thất bại ;, nhưng nếu muốn thành công hoàn toàn thì công việc đầu tiên bắt đầu sử dụng tắt máy&&


14

a ; bsẽ chạy b bất kể trạng thái thoát của a. a && bsẽ chạy b chỉ khi a thành công.

Điều này là cần thiết và đủ để trả lời cho 3 câu hỏi đầu tiên. Cụ thể, số 2 quá rộng và không thể đưa ra câu trả lời dứt khoát "một" - cách tốt nhất của bạn là quyết định theo từng trường hợp.

Đối với câu hỏi thứ 4: Chúng là cú pháp Bash .

Không có nguy hiểm nội tại trong việc sử dụng một trong hai. Một lần nữa, định nghĩa trên là đủ. Nó ngụ ý rằng bạn sẽ viết &&khi bcó tác dụng ngoài ý muốn nếu akhông thành công. Không cần thêm quy tắc hay giải thích, IMHO.


1

A; B # Chạy A và sau đó B, bất kể thành công của A

A && B # Chạy B khi và chỉ khi A thành công

Một | | B # Chạy B khi và chỉ khi A thất bại

A & # Chạy A trong nền.

Một quy tắc rất tốt của ngón tay cái. Tôi sẽ nói thêm rằng trong một số trường hợp, sử dụng các lệnh này trong một lớp con có ý nghĩa khi chúng ta muốn coi chúng là một đơn vị hoặc chúng ta không muốn kết hợp một số kết quả hoạt động với trình bao hiện tại.

Ví dụ:

-concatenate đầu ra của hai lệnh:

(ls foo; ls bar) > single-result.txt

-đi vào một thư mục và thực hiện một lệnh từ đó trong khi không thay đổi thư mục hiện tại của shell:

(cd target-directory && jar -xf ../my-jar)
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.