2013-08-19 29 views
12

Trong bash, tôi muốn nói "nếu một tệp không chứa XYZ, thì" làm một loạt các thứ. Cách tự nhiên nhất để chuyển mã này thành mã là một cái gì đó như:Bash có điều kiện trên mã thoát lệnh

if [ ! grep --quiet XYZ "$MyFile" ] ; then 
    ... do things ... 
fi 

Nhưng tất nhiên, cú pháp Bash không hợp lệ. Tôi có thể sử dụng backticks, nhưng sau đó tôi sẽ kiểm tra đầu ra của tập tin. Hai lựa chọn thay thế tôi có thể nghĩ đến là:

grep --quiet XYZ "$MyFile" 
if [ $? -ne 0 ]; then 
    ... do things ... 
fi 

grep --quiet XYZ "$MyFile" || 
    ( ... do things ... 
    ) 

Tôi thích loại thứ hai, đó là lispy hơn và || cho luồng điều khiển không phải là không phổ biến trong các ngôn ngữ kịch bản. Tôi cũng có thể thấy đối số cho người đầu tiên, mặc dù khi người đó đọc dòng đầu tiên, họ không biết lý do tại sao bạn đang thực thi grep, có vẻ như bạn đang thực hiện nó cho hiệu ứng chính, thay vì chỉ kiểm soát một chi nhánh trong kịch bản.

Có cách nào thứ ba, trực tiếp hơn sử dụng tuyên bố if và có grep trong điều kiện không?

+0

có thể trùng lặp của [gặp "toán tử đơn nhất mong đợi" trong tập lệnh bash] (http://stackoverflow.com/questions/10586213/encounter-unary-operator-expected-in-bash-script) – tripleee

Trả lời

20

Có có:

if grep --quiet ..... 
then 
    # If grep finds something 
fi 

hoặc nếu grep không

if ! grep --quiet ..... 
then 
    # If grep doesn't find something 
fi 
+0

D'oh! Cảm ơn. Trong phòng thủ của tôi, tôi đã không thấy rằng trong bất kỳ hướng dẫn, ngay cả những người mà nói về kiểm tra mã thoát của một lệnh. –

+1

'[' là loại bí danh cho 'kiểm tra' (cũng yêu cầu'] '). Vì vậy, nếu 'if [...]' tương đương với 'nếu test ...' – coldfix

+0

Điều gì xảy ra nếu bạn muốn kiểm tra nhiều điều kiện, một trong số đó là trạng thái thoát của lệnh? Như trong: 'if [[$ OS ==" cửa sổ "&& command-exit-status == 0]]; ...' ? Tôi có thể chạy lệnh đầu tiên và lưu '$?' Tất nhiên, nhưng tôi muốn phím tắt '&&' hành vi để nó không chạy lệnh trừ khi '$ OS == windows'. Bất kỳ ý tưởng tốt? – GaryO

2

Đây là một vấn đề của hương vị vì không rõ ràng là nhiều giải pháp làm việc. Khi tôi đối phó với một vấn đề như thế này, tôi thường áp dụng wc -l sau grep để đếm các dòng phù hợp. Sau đó, bạn có một số nguyên duy nhất mà bạn có thể đánh giá trong một điều kiện thử nghiệm. Nếu câu hỏi duy nhất là liệu có một trận đấu ở tất cả (số dòng phù hợp với không quan trọng), sau đó áp dụng wc lẽ là OTT và đánh giá các mã trở lại grep 's có vẻ là giải pháp tốt nhất:

Thông thường, trạng thái thoát là 0 nếu tìm thấy các dòng được chọn và 1 nếu không. Nhưng trạng thái thoát là 2 nếu xảy ra lỗi, trừ khi sử dụng tùy chọn -q hoặc --quiet hoặc --silent và tìm thấy một dòng được chọn. Tuy nhiên, lưu ý rằng POSIX chỉ ủy quyền cho các chương trình như grep, cmp và khác biệt, rằng trạng thái thoát trong trường hợp lỗi lớn hơn 1; nó là vì thế nên, vì lợi ích của tính di động, sử dụng logic mà kiểm tra cho tình trạng chung này thay vì bình đẳng nghiêm ngặt với 2.

7

Bạn không cần [] (test) để kiểm tra sự trở lại giá trị của một lệnh. Chỉ cần thử:

if ! grep --quiet XYZ "$MyFile" ; then