Có sự khác biệt giữa '&&' và ';' các ký hiệu trong một thiết bị đầu cuối BASH tiêu chuẩn?


56

Dường như cả hai đều báo hiệu BASH bắt đầu với một lệnh khác theo các ký hiệu nhưng có sự khác biệt rõ ràng không?

Câu trả lời:


75

Với dòng này:

command1 && command2

lệnh2 sẽ được thực thi nếu (và chỉ khi) lệnh1 trả về trạng thái thoát bằng 0, trong khi trong dòng này:

command1 ; command2

cả lệnh1 và lệnh2 sẽ được thực thi bất kể Dấu chấm phẩy cho phép bạn gõ nhiều lệnh trên một dòng.


1
Hấp dẫn! Tôi đã nghĩ rằng nó có thể là một cách thoải mái hơn. Cảm ơn bạn!

42

Bạn có thể thử sự khác biệt cho chính mình:

  1. ls /invalid/path && echo "hello!"
    vì / không hợp lệ / đường dẫn không tồn tại, tôi không thể hiển thị cho bạn danh sách thư mục. Nó sẽ thất bại với thông báo lỗi: "ls: / không hợp lệ / đường dẫn: Không có tệp hoặc thư mục như vậy".
    Các nửa cuối của lệnh (echo "hello!") Được không bao giờ thậm chí thực hiện vì nửa đầu thất bại.

  2. ls /invalid/path ; echo "hello!"
    Thông báo lỗi tương tự xuất hiện như trước, nhưng lần này, phần thứ hai được thực thi !
    ls: / không hợp lệ / đường dẫn: Không có tập tin hoặc thư mục như vậy
    xin chào!

Tại sao điều này hữu ích?
Giả sử bạn muốn trích xuất một tệp có tên archive.tar.gz
Bạn có thể sử dụng lệnh tar zxvf archive.tar.gz && rm archive.tar.gz.
Nếu vì bất kỳ lý do nào, việc trích xuất kho lưu trữ không thành công, phần thứ hai không được thực thi! Bạn có thể thử lại.

Nếu bạn dùng ; trong tình huống tương tự, kho lưu trữ sẽ bị xóa và bạn không thể thử lại.


8

&&AND, có nghĩa là lệnh thứ hai sẽ chỉ thực thi nếu lệnh đầu tiên trả về true (không có lỗi).


1
&& là "sau đó" (không phải là "và") ... hãy xem câu trả lời của tôi
Peter.O

2
@fred Tôi muốn nói đó là "và" với đánh giá ngắn mạch - nếu phần đầu tiên không đúng thì nó biết rằng tổng kết quả phải là sai, vì vậy nó bỏ qua phần thứ hai. Nhưng đồng ý rằng nghĩ về nó như một "sau đó" hiếm khi tạo ra nhiều sự khác biệt trong bối cảnh này.
jg-faustus

2
@fred Mặc dù về mặt khái niệm có thể dễ hiểu hơn theo cách đó, tôi không đồng ý với tuyên bố của bạn. Ý tưởng đơn giản là với bất kỳ AND thực thi nào , tham số thứ 2 sẽ trở nên không liên quan nếu cái đầu tiên bằng falsevà do đó mã bên dưới được tối ưu hóa để hoãn đánh giá tham số thứ 2 cho đến khi nó biết cái đầu tiên là gì.
Phường Muylaert

2
@fred Tôi không chắc ví dụ nào đang cố gắng thực hiện. &&chỉ là một toán tử nhị phân, một hàm. Điều "đặc biệt" duy nhất là ký hiệu infix (là tiêu chuẩn cho hầu hết các loại toán tử này) và việc thực thi toán hạng thứ hai bị trì hoãn. Việc thực thi bị trì hoãn đó thực sự mang lại cho nó khả năng được sử dụng như một thứ có thể được xem một cách khái niệm như một iftuyên bố trong bối cảnh này , nhưng điều đó không làm mất đi thực tế rằng việc sử dụng dự định ban đầu của nó nằm trong điều kiện của một iftuyên bố thực tế . Việc sử dụng ở đây thực sự là một "hack".
Phường Muylaert

3
@fred Tất nhiên đó không phải là một nhà điều hành ternary, nó chỉ là sự kế thừa của hai hoạt động a && b || c = (a && b) || c. Trình tự đánh giá đơn giản. Thực sự không có gì bí ẩn ở đó. Nếu bạn viết chúng giống như các hàm thông thường của bạn, nó sẽ trông giống như vậy or(and(a, b), c). Logic này giống nhau trong một ifđiều kiện cũng như khi nhập thẳng vào dòng lệnh bởi vì &&||toán tử , chúng lấy hai toán hạng và chúng trả về một toán hạng khác.
Phường Muylaert

8

Cập nhật : Tôi đã thêm dưới dạng tập lệnh để đánh dấu một số bẫy có thể:

Bởi vì không ai khác đã đề cập đến "||", tôi sẽ

Update2 : một số từ ngữ quan trọng ở đây
&& giống như một câu "sau đó" của câu lệnh "if" đáp ứng với "true"

| | là KHÔNG thích "khác" của một "nếu" Statment ..
|| giống như một "sau đó" của một câu lệnh "nếu" phản hồi lại "sai"

Cụ thể hơn, && kiểm tra $? giá trị trả về của câu lệnh được thực hiện gần đây nhất trước đó và chuyển điều khiển sang câu lệnh hoặc shell con ngay sau dấu && ... nó chỉ vượt qua điều khiển nếu $? là đúng.

| | là tương tự và thường được thấy sau câu lệnh &&, nhưng nó kiểm tra giá trị trả về sai ($?) từ câu lệnh được thực hiện gần đây nhất trước đó ... NB! , Nota Bene! Lưu ý rõ! .... nếu câu lệnh tiền xử lý là câu lệnh && sẽ truy xuất sai khi bạn cho rằng nó là đúng, thì || sẽ phản hồi sai, vì vậy trộn cả hai trên cùng một dòng có thể có rủi ro

Điểm chính tôi đang cố gắng thực hiện liên quan đến một lỗi tôi đã làm. tức là:
## [[điều kiện]] && A || B
được không không cư xử giống như một C C ++ style ternary /. tức là:
// (điều kiện)? A: B
Xem tập lệnh bên dưới để biết ví dụ về kết quả "không mong muốn" từ "A"

Bài kiểm tra cơ bản và && và || tất cả các câu lệnh phải nằm trên cùng một dòng ...


Chạy tập lệnh này để xem mọi thứ có thể sai khi sử dụng && và ||
Câu lệnh được thực hiện gần đây nhất có thể không phải là câu bạn mong đợi ..

[[điều kiện]] && echo Xin chào | | echo Goodbye .... thường an toàn,
vì tiếng vang được hình thành tốt sẽ trở lại đúng.
Nhưng những gì về việc truy cập một tập tin không thoát?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \$0  0   rc=$? ..&&.. condition is true" || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \$0  1   rc=$? ..&&.. condition is true" || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \$0  0   rc=$? ..||.. condition is true" && echo "  \$0  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \$0  1   rc=$? ..||.. condition is true" && echo "  \$0  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"

exit 


1

thử

sai && tiếng vang "xin chào"

sai trái ; tiếng vang "xin chào"

thấy sự khác biệt


0

Lệnh (hàm, trong trường hợp tập lệnh) sau &&được thực thi tùy thuộc vào RETVAL của lệnh đầu tiên (hàm, trong trường hợp tập lệnh). Nó buộc lệnh đầu tiên trả về giá trị 0, nếu thành công. Chúng ta có thể kiểm tra giá trị trả về để thực hiện các lệnh tiếp theo.

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.