Dường như có một số hiểu lầm ở đây về việc xây dựng Bash true
, và cụ thể hơn, về cách Bash mở rộng và diễn giải các biểu thức bên trong ngoặc.
Mã trong câu trả lời của miku hoàn toàn không liên quan gì đến nội dung Bash true
, cũng /bin/true
như bất kỳ hương vị nào khác của true
lệnh. Trong trường hợp này, true
không có gì khác hơn một chuỗi ký tự đơn giản và không có lệnh gọi true
lệnh / dựng sẵn nào được thực hiện, không phải bằng phép gán biến, cũng không phải bằng cách đánh giá biểu thức điều kiện.
Đoạn mã sau giống hệt như mã trong câu trả lời của miku:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
Sự khác biệt duy nhất ở đây là bốn ký tự được so sánh là 'y', 'e', 'a' và 'h' thay vì 't', 'r', 'u' và 'e'. Đó là nó. Không có nỗ lực nào để gọi một lệnh hoặc nội dung được đặt tên yeah
, cũng không có (trong ví dụ của miku) bất kỳ loại xử lý đặc biệt nào đang diễn ra khi Bash phân tích mã thông báo true
. Nó chỉ là một chuỗi, và một chuỗi hoàn toàn tùy ý ở đó.
Cập nhật (2014/02/19): Sau khi theo liên kết trong câu trả lời của miku, bây giờ tôi thấy một số sự nhầm lẫn đến từ đâu. Câu trả lời của Miku sử dụng dấu ngoặc đơn, nhưng đoạn mã anh liên kết đến không sử dụng dấu ngoặc. Nó chỉ:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Cả hai đoạn mã sẽ hành xử theo cùng một cách, nhưng dấu ngoặc thay đổi hoàn toàn những gì đang diễn ra dưới mui xe.
Đây là những gì Bash đang làm trong từng trường hợp:
Không có dấu ngoặc:
- Mở rộng biến
$the_world_is_flat
thành chuỗi "true"
.
- Cố gắng phân tích chuỗi
"true"
như một lệnh.
- Tìm và chạy
true
lệnh (có thể là lệnh dựng sẵn hoặc /bin/true
, tùy thuộc vào phiên bản Bash).
- So sánh mã thoát của
true
lệnh (luôn luôn là 0) với 0. Hãy nhớ lại rằng trong hầu hết các shell, mã thoát 0 biểu thị thành công và bất cứ điều gì khác chỉ ra thất bại.
- Vì mã thoát là 0 (thành công), hãy thực hiện mệnh đề
if
của câu lệnhthen
Chân đế:
- Mở rộng biến
$the_world_is_flat
thành chuỗi "true"
.
- Phân tích biểu thức điều kiện hiện được mở rộng đầy đủ, có dạng
string1 = string2
. Các =
nhà điều hành là bash của so sánh chuỗi điều hành. Vì thế...
- Làm một chuỗi so sánh trên
"true"
và "true"
.
- Đúng, hai chuỗi là như nhau, vì vậy giá trị của điều kiện là đúng.
- Thực hiện mệnh đề
if
của tuyên bố then
.
Mã no-ngoặc hoạt động, bởi vì true
lệnh trả về mã thoát là 0, cho biết thành công. Mã ngoặc vuông hoạt động, bởi vì giá trị của $the_world_is_flat
nó giống hệt với chuỗi ký tự true
ở bên phải của =
.
Chỉ cần lái xe về nhà, hãy xem xét hai đoạn mã sau:
Mã này (nếu chạy với quyền root) sẽ khởi động lại máy tính của bạn:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Mã này chỉ in "Đẹp thử." Lệnh khởi động lại không được gọi.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Cập nhật (2014-04-14) Để trả lời câu hỏi trong các nhận xét liên quan đến sự khác biệt giữa =
và ==
: AFAIK, không có sự khác biệt. Các ==
nhà điều hành là một từ đồng nghĩa Bash cụ thể cho =
, và như xa như tôi đã nhìn thấy, họ làm việc giống hệt nhau trong mọi hoàn cảnh.
Lưu ý, tuy nhiên, tôi đặc biệt nói về =
và ==
toán tử so sánh chuỗi được sử dụng trong cả hai [ ]
hoặc [[ ]]
kiểm tra. Tôi không gợi ý điều đó =
và ==
có thể hoán đổi cho nhau ở mọi nơi trong bash.
Ví dụ, rõ ràng là bạn không thể thực hiện gán biến ==
, chẳng hạn như var=="foo"
(về mặt kỹ thuật bạn có thể làm điều này, nhưng giá trị var
sẽ là "=foo"
, bởi vì Bash không nhìn thấy một ==
toán tử ở đây, nó nhìn thấy một =
toán tử (gán), theo sau là các giá trị văn chương ="foo"
, mà chỉ trở thành"=foo"
).
Ngoài ra, mặc dù =
và ==
có thể hoán đổi cho nhau, bạn nên nhớ rằng các bài kiểm tra đó hoạt động như thế nào tùy thuộc vào việc bạn có sử dụng nó bên trong [ ]
hay không [[ ]]
, và cũng có thể trích dẫn các toán hạng hay không. Bạn có thể đọc thêm về điều đó trong Hướng dẫn lập trình Bash nâng cao: 7.3 Toán tử so sánh khác (cuộn xuống phần thảo luận về =
và ==
).
true
vàfalse
trong bối cảnh của hầu hết các đoạn dưới đây chỉ là các chuỗi đơn giản, không phải làbash built-ins
!!! Xin vui lòng đọc câu trả lời của Mike Holt dưới đây. (Đây là một ví dụ trong đó câu trả lời được bình chọn và chấp nhận cao là IMHO khó hiểu và làm mờ nội dung sâu sắc trong các câu trả lời ít được bình chọn hơn)