Trong một tập lệnh bash, sử dụng câu lệnh điều kiện hoặc điều kiện trong một câu lệnh if nếu


129

Câu hỏi này là một phần tiếp theo của câu hỏi trước đây của tôi . Người dùng trên trang này vui lòng giúp tôi xác định cách viết một forvòng lặp bash lặp lại trên các giá trị chuỗi. Ví dụ, giả sử rằng một biến điều khiển vòng fnamelặp lặp trên các chuỗi "a.txt" "b.txt" "c.txt". Tôi muốn echo"có!" khi fnamecó giá trị "a.txt"hoặc "c.txt", và echo"không!" nếu không thì. Tôi đã thử tập lệnh bash shell sau:

#!/bin/bash

for fname in "a.txt" "b.txt" "c.txt"
do
 echo $fname
 if [ "$fname" = "a.txt" ] | [ "$fname" = "c.txt" ]; then
 echo "yes!"
else
 echo "no!"
fi
done

Tôi có được đầu ra:

a.txt

Không!

b.txt

Không!

c.txt

Đúng!

Tại sao iftuyên bố rõ ràng mang lại sự thật khi fnamecó giá trị "a.txt"? Tôi đã sử dụng |không chính xác?


3
Trong bash, 'hoặc' toán tử là '||' (Kiểu C).
Marius Cotofana

3
Bạn cũng có thể sử dụng -otrong cùng [ ].
Thor

6
@Thor Tôi thích ||và tách biệt [ ]hơn -ovề tính di động chỉ vì [không được đảm bảo hỗ trợ nhiều hơn 4 đối số. Tất nhiên, nếu ngôn ngữ đích là bash, không ai nên sử dụng [dù sao đi nữa vì bash[[vượt trội hơn về nhiều mặt.
jw013

2
@ jw013 Cảm ơn. Điều này có nghĩa là tôi nên sử dụng if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]]chứ không phải if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]?
Andrew

5
@Andrew Điều đó đúng, nếu như bạn đang khai báo shebang như bash, như bạn đã làm. Một lợi thế của [[nó là nó không thực hiện phân tách từ (trường hợp đặc biệt) nên rất [[ $unquoted_var = string ]]an toàn.
jw013

Câu trả lời:


229

Nếu bạn muốn nói ORsử dụng ống đôi ( ||).

if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]

(Mã OP ban đầu sử dụng |chỉ đơn giản là dẫn đầu ra của bên trái sang bên phải, giống như bất kỳ đường ống thông thường nào hoạt động.)


4
Hơn nữa, ||không thực hiện logic "HOẶC" tiêu chuẩn - nó ngắn mạch và lệnh thứ hai chỉ được chạy nếu lần đầu tiên thất bại.
Holdenweb

13
@keepenweb Tôi khá chắc chắn rằng hầu hết các ngôn ngữ được tối ưu hóa hiện đại đều hoạt động theo cùng một cách. Không cần phải sử dụng chu kỳ CPU để đánh giá điều kiện thứ hai ORnếu điều kiện thứ nhất đánh giá đúng.
bahamat

1
Tôi nghĩ bash thích ==nhưng sau khi nhìn thấy câu trả lời này, tôi quyết định tìm nó lên. Rõ ràng, "nó có thể được sử dụng nhưng không phải là tiêu chuẩn". Tôi nghĩ tôi sẽ đặt cái này ở đây cho người khác nếu bạn tò mò: stackoverflow.com/a/2237103
harperville

Đây là những gì testtrang người đàn ông đề xuất quá
cdosborn

2
Bạn cũng có thể sử dụng các kiểm tra khung đôi - if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]](Nếu bạn muốn hoặc cần có chức năng bổ sung liên quan [[ ]]).
HankCa
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.