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?
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:
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.
Bạn có thể thử sự khác biệt cho chính mình:
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.
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.
&&
là 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).
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 false
và 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ì.
&&
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 if
tuyê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 if
tuyên bố thực tế . Việc sử dụng ở đây thực sự là một "hack".
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ì &&
và ||
là 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.
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
thử
sai && tiếng vang "xin chào"
và
sai trái ; tiếng vang "xin chào"
thấy sự khác biệt
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.