Mục đích của các trò chơi & & # trong một lệnh shell là gì?


Câu trả lời:


399

&&cho phép bạn làm một cái gì đó dựa trên việc lệnh trước đó đã hoàn thành thành công hay chưa - đó là lý do tại sao bạn có xu hướng thấy nó bị xiềng xích do_something && do_something_else_that_depended_on_something.


391

Hơn nữa, bạn cũng có ||cái hợp lý hoặc, và cũng ;chỉ là một dấu phân cách không quan tâm đến những gì xảy ra với lệnh trước đó.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Một số chi tiết về điều này có thể được tìm thấy ở đây Danh sách các lệnh trong Hướng dẫn Bash.


5
Có lẽ bạn muốn thêm false && echo "Will not be printed".
MTSan

112

dòng lệnh - mục đích của là &&gì?

Trong vỏ, khi bạn nhìn thấy

$ command one && command two

mục đích là để thực hiện lệnh theo sau &&chỉ khi lệnh đầu tiên thành công. Đây là thành ngữ của vỏ Posix và không chỉ được tìm thấy ở Bash.

Nó có ý định ngăn chặn quá trình chạy thứ hai nếu lần đầu tiên thất bại.

Bạn có thể nhận thấy tôi đã sử dụng từ "ý định" - đó là lý do chính đáng. Không phải tất cả các chương trình đều có cùng một hành vi, vì vậy để điều này hoạt động, bạn cần hiểu chương trình coi "lỗi" là gì và cách nó xử lý nó bằng cách đọc tài liệu và, nếu cần, mã nguồn.

Shell của bạn coi giá trị trả về là 0 là true, các số dương khác là false

Các chương trình trả lại một tín hiệu về thoát. Họ sẽ trả về 0 nếu thoát thành công hoặc lớn hơn 0 nếu không. Điều này cho phép một lượng giao tiếp hạn chế giữa các quy trình.

Cái &&này được gọi là AND_IFtrong ngữ pháp shell posix , là một phần của and_ordanh sách các lệnh, cũng bao gồm cái ||OR_IFngữ nghĩa tương tự.

Biểu tượng ngữ pháp, trích dẫn từ tài liệu:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

Và Ngữ pháp (cũng được trích dẫn từ tài liệu), cho thấy rằng bất kỳ số AND_IFs ( &&) và / hoặc OR_IFs ( ||) nào cũng có thể được xâu chuỗi lại với nhau (như and_orđược định nghĩa đệ quy):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Cả hai toán tử đều có quyền ưu tiên như nhau và được đánh giá từ trái sang phải (chúng là liên kết trái). Như các tài liệu nói:

Một AND-ORdanh sách là một chuỗi gồm một hoặc nhiều đường ống được phân tách bởi các toán tử "&&""||".

Một danh sách là một chuỗi của một hoặc nhiều AND-OR danh sách được phân cách bởi các nhà khai thác ';''&'và tùy chọn chấm dứt bởi ';', '&'hoặc.

Các toán tử "&&""||"sẽ có quyền ưu tiên như nhau và sẽ được đánh giá với tính kết hợp trái. Ví dụ, cả hai lệnh sau chỉ ghi thanh vào đầu ra tiêu chuẩn:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. Trong trường hợp đầu tiên, false là một lệnh thoát với trạng thái 1

    $ false
    $ echo $?
    1

    có nghĩa là echo fookhông chạy (tức là shortcircuiting echo foo). Sau đó, lệnh echo barđược thực thi.

  2. Trong trường hợp thứ hai, lối thoát thực sự với mã 0

    $ true
    $ echo $?
    0

    và do đó echo fookhông được thực thi, sau đó echo barđược thực thi.


31

Một cách sử dụng khá phổ biến cho '&&' là biên dịch phần mềm với chế độ tự động. Ví dụ:

./configure --prefix=/usr && make && sudo make install

Về cơ bản nếu cấu hình thành công, make được chạy để biên dịch và nếu thành công, make được chạy dưới quyền root để cài đặt chương trình. Tôi sử dụng điều này khi tôi gần như chắc chắn rằng mọi thứ sẽ hoạt động và nó cho phép tôi làm những việc quan trọng khác như xem stackoverflow không phải là "giám sát" tiến trình.

Đôi khi tôi thực sự bị mang đi ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Tôi làm điều này khi ví dụ làm một linux từ hộp đầu.


2
Tốt trong REPL, nhưng đối với các kịch bản tôi thích set -o errexitBash hơn.
Franklin Yu

19

&&chuỗi lệnh với nhau. Các lệnh liên tiếp chỉ thực hiện nếu các lệnh trước thành công.

Tương tự, ||sẽ cho phép lệnh liên tiếp thực thi nếu trước đó không thành công.

Xem lập trình Bash Shell .


8

Xem ví dụ:

mkdir test && echo "Something" > test/file

Shell sẽ cố gắng tạo thư mục testvà sau đó, chỉ khi nó thành công nó sẽ thử tạo tập tin bên trong nó.

Vì vậy, bạn có thể làm gián đoạn một chuỗi các bước nếu một trong số chúng thất bại.


8

Đó là thực hiện một tuyên bố thứ hai nếu tuyên bố đầu tiên kết thúc thành công. Giống như một câu lệnh if:

 if (1 == 1 && 2 == 2)
  echo "test;"

Lần đầu tiên thử nếu 1 == 1, nếu đó là sự thật, nó sẽ kiểm tra nếu 2 == 2


1
Ai đó có thể giải thích lý do tại sao điều này đã bị hạ thấp cho người dùng vấp phải câu hỏi?
dùng3243242

1
@ user3243242 không sai, chỉ là một ví dụ tồi để minh họa việc sử dụng&&
dan

Đó là một cái nhìn sâu sắc tuyệt vời về cách ifcác bài kiểm tra làm việc trong bash. Tôi chưa bao giờ nghĩ nó giống như một chuỗi các lệnh so sánh, phá vỡ khi bất kỳ trong số chúng thất bại. Vậy là bạn đã có upvote của tôi :)
PiRK

1
Hậu quả là bạn có thể có hành vi ngược lại bằng cách sử dụng ||, để xâu chuỗi các lệnh cho đến khi một trong số chúng thành công: eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2: chỉ thực hiện lệnh_2 khi lệnh_1 được thực thi thành công.

command_1 || command_2: chỉ thực hiện lệnh_2 khi lệnh_1 không được thực thi thành công.

Cảm thấy tương tự như cách một điều kiện 'nếu' được thực thi trong ngôn ngữ lập trình chính thống, như, trong if (condition_1 && condition_2){...}điều kiện_2 sẽ bị bỏ qua nếu điều kiện_1 là falsevà trong if (condition_1 || condition_2){...}điều kiện_2 sẽ bị bỏ qua nếu điều kiện_1 là true. Hãy xem, đó là cùng một mẹo bạn sử dụng để mã hóa :)


Tôi không biết ý của bạn là 'hoàn toàn ngược lại', nhưng $ echo '1' || echo '2' chỉ in '1'. và $ sai_command || echo '2' in thông báo lỗi và '2' trên dòng tiếp theo. Bạn có thể giải thích thêm một chút về những gì bạn nghĩ là sai về nó?
Xiaonin Li

ho anh bạn, tôi chắc chắn đã quá mệt mỏi ngày hôm qua xin lỗi vì điều đó, chỉ có tôi: / Tôi cần bạn chỉnh sửa câu trả lời nếu bạn muốn tôi upvote (để trả lời 0, ngay bây giờ stackoverflow yêu cầu chỉnh sửa để tôi không thể)
Arount

@Arount, không sao đâu. Vì vậy, tôi chỉ cần gửi một chỉnh sửa. Vì vậy, bạn có thể loại bỏ bỏ phiếu xuống bây giờ?
Xiaonin Li

vâng, một lần nữa, xin lỗi, thực sự
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Khi chương trình kiểm tra lệnh if, thì chương trình sẽ tạo một số gọi là mã thoát, nếu cả hai điều kiện đều đúng, mã thoát là 0 (0), nếu không, mã thoát là số dương. chỉ khi hiển thị Bằng nếu mã thoát được tạo ra 0 (0) có nghĩa là cả hai điều kiện đều đúng.


Chào mừng đến với stackoverflow. Vui lòng đảm bảo đoạn mã của bạn hoạt động trước khi đăng ở đây. Bạn phải sửa nóif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu

1
Cảm ơn bạn @ZhengQu vì lệnh của bạn, đã xong.
Amin
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.