2012-01-19 29 views
198

Tôi đoán tôi không rõ ràng về cách thực hiện "và" các bài kiểm tra. Tôi muốn chắc chắn rằng một đối số tồn tại đã hoạt động tốt với [ -e $VAR ] nhưng hóa ra nó cũng được đánh giá là đúng trên chuỗi rỗng; mà tôi không muốn.

Làm cách nào để 'và' chúng cùng nhau? Hay có một bài kiểm tra đơn nhất khác để hoàn thành những gì tôi muốn?

Trả lời

361
if [ ! -z "$var" ] && [ -e "$var" ]; then 
     # something ... 
fi 
+7

Giải pháp này hoạt động ngay cả trong các vỏ tuân thủ nghiêm ngặt POSIX và do đó cũng trong 'bash'; tuy nhiên, để tận dụng tối đa "bashisms", hãy xem câu trả lời của @ paxdiablo. – mklement0

+1

Rất vui khi thấy điều này được khuyên thay vì '-a' đã lỗi thời. –

+0

Tôi tìm thấy một giải thích tuyệt vời và chi tiết khác - http://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash – valentt

4
if [ -n "$var" -a -e "$var" ]; then 
    do something ... 
fi 

 

+9

Vì 'POSIX' không xác định hành vi của '[' với các bộ kiểm thử phức tạp, chúng ta nên tránh sử dụng '-a' hoặc' -o' với '['. Tôi đọc nó [ở đây] (http://mywiki.wooledge.org/BashGuide/TestsAndConditionals?highlight=%28conditional%29#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29). –

+1

@ jaypal-singh Bạn nói đúng, nhưng chủ đề có thẻ 'bash' và không đề cập đến POSIX, vì vậy tôi đăng phiên bản này hoạt động dưới' bash' và một số vỏ hiện đại khác. –

+2

Nếu bạn giả sử sử dụng 'bash' hoặc các shell hiện đại khác, thậm chí còn có * ít * lý do để đề xuất' -a'. – chepner

43

Từ bash manpage:

[[ expression ]] - trả lại trạng thái 0 hoặc 1 tùy thuộc vào đánh giá của biểu thức biểu thức điều kiện.

Và, cho các biểu thức, một trong những lựa chọn là:

expression1 && expression2 - đúng nếu cả hai expression1expression2 là đúng sự thật.

Vì vậy, bạn có thể and chúng lại với nhau như sau (-n là đối diện của -z vì vậy chúng tôi có thể thoát khỏi những !):

if [[ -n "$var" && -e "$var" ]] ; then 
    echo "'$var' is non-empty and the file exists" 
fi 

Tuy nhiên, tôi không nghĩ rằng nó là cần thiết trong trường hợp này , -e xyzzy là true nếu tệp xyzzy tồn tại và có thể dễ dàng xử lý các chuỗi trống. Nếu đó là những gì bạn muốn thì bạn không thực sự cần kiểm tra -z không rỗng:

pax> VAR=xyzzy 
pax> if [[ -e $VAR ]] ; then echo yes ; fi 
pax> VAR=/tmp 
pax> if [[ -e $VAR ]] ; then echo yes ; fi 
yes 

Nói cách khác, chỉ cần sử dụng:

if [[ -e "$var" ]] ; then 
    echo "'$var' exists" 
fi 
+0

Chúng tôi có thể rút ngắn nó bằng '[[-e" $ var "]] && echo" '$ var' tồn tại "' –

+1

Có, nếu đó là một lớp lót (như ví dụ của tôi). Tôi sẽ không làm điều đó nếu khối điều kiện phức tạp hơn nhiều. – paxdiablo

2

Đơn giản chỉ cần trích dẫn biến của bạn:

[ -e "$VAR" ] 

Điều này đánh giá là [ -e "" ] nếu $VAR trống.

Phiên bản của bạn không hoạt động vì phiên bản này đánh giá là [ -e ]. Bây giờ trong trường hợp này, bash chỉ đơn giản là kiểm tra nếu đối số duy nhất (-e) là một chuỗi không trống.

Từ manpage:

thử nghiệm và [đánh giá biểu thức có điều kiện sử dụng một bộ quy tắc dựa trên số lượng các đối số. ...

1 đối số

Biểu thức là đúng nếu và chỉ khi đối số không rỗng.

(Ngoài ra, giải pháp này có lợi ích bổ sung làm việc với các tên tập tin chứa khoảng trắng)

0

Tôi tìm thấy một câu trả lời bây giờ, cảm ơn vì lời đề nghị của bạn!

for e in ./*.cutoff.txt; do 
if grep -q -E 'COX1|Cu-oxidase' $e 
then 
    echo xyz >$e.match.txt 
else 
    echo 
fi 

if grep -q -E 'AMO' $e 
then 
    echo abc >$e.match.txt 
else 
    echo 
fi; done 

mọi nhận xét về điều đó? Nó có vẻ không hiệu quả với grep hai lần, nhưng nó hoạt động ...

Các vấn đề liên quan