2012-05-14 12 views
12

trong tập lệnh bash của tôi, tôi có hàm trả về 0 hoặc 1 (đúng hoặc sai) cho điều kiện hàm chính sau này.gặp phải "toán tử đơn nhất được mong đợi" trong bash script

function1() { 
    if [[ "${1}" =~ "^ ...some regexp... $" ]] ; then 
     return 1 
    else 
     return 0 
    fi 
} 

sau đó chức năng chính của tôi:

main() { 
    for arg in ${@} ; do 
     if [ function1 ${arg} ] ; then 
      ... 
     elif [ ... ] ; then 
      ... 
     fi 
    done 
} 

Tuy nhiên, khi tôi chạy kịch bản này nó luôn luôn đã cho tôi một msg lỗi "[: Function1: nhà điều hành unary dự kiến"

bất cứ ai có thể giúp đỡ tôi xin vui lòng?

+1

Lưu ý rằng, ít nhất trong phiên bản bash 4, bạn không nên trích dẫn cụm từ thông dụng : làm như vậy buộc kết hợp chuỗi đơn giản - [được ghi lại ở đây] (http://www.gnu.org/software/bash/manual/bashref.html#index-g_t_005b_005b-57). Ngoài ra, bạn nên sử dụng 'for arg in" $ @ "' với dấu ngoặc kép hoặc đơn giản hơn 'cho arg; do ... ' –

+1

Bạn nên đặt regex của mình vào một biến. 'pattern = '^ ... một số regexp ... $'; nếu [[$ 1 = ~ $ mẫu]] '. Lưu ý rằng bên trong dấu ngoặc vuông đôi, không cần trích dẫn biến và như glenn đã nói, regex (biến) không bao giờ được trích dẫn. –

Trả lời

28

Bạn đang mắc phải sai lầm phổ biến khi giả định rằng [ là một phần của cú pháp của lệnh if. Không phải vậy; cú pháp của if chỉ đơn giản là

if command; then 
    ... things which should happen if command's result code was 0 
else 
    ... things which should happen otherwise 
fi 

Một trong những command s chung chúng tôi sử dụng là [ mà là một bí danh cho lệnh test. Đó là một lệnh đơn giản để so sánh chuỗi, số và tệp. Nó chấp nhận một sự kết hợp khá hẹp của các đối số, và có xu hướng tạo ra các thông báo lỗi khó hiểu và gây nhầm lẫn nếu bạn không vượt qua nó các đối số dự kiến. (Hay đúng hơn, các thông báo lỗi là đầy đủ và hữu ích khi bạn quen với nó, nhưng chúng có thể dễ dàng bị hiểu lầm nếu bạn không được sử dụng.)

Trong chức năng main, cuộc gọi đến [ xuất hiện sai chỗ. Bạn có thể có nghĩa là

if function "$arg"; then 
    ... 
elif ... ; then ... 

Nhân tiện, bạn nên luôn trích dẫn các chuỗi của mình. Sử dụng "$1" không $1"$arg" thay vì $arg.

Lý do lịch sử cho test như một bồn rửa chung mà các tác giả không muốn thực hiện một phần cú pháp của if là một trong những thiết kế kém hấp dẫn của vỏ Bourne gốc. Bash và zsh các lựa chọn thay thế ít khó sử dụng hơn (như [[ dấu ngoặc kép trong bash, mà bạn sử dụng trong định nghĩa function1), và tất nhiên, POSIX test là rất tốt hơn so với sáng tạo ban đầu từ Bell Labs.

Là một làm rõ thêm, chức năng của bạn có thể được đơn giản hóa để chỉ

function1() { 
    ! [[ "$1" =~ "^ ...some regexp... $" ]] 
} 

Đó là, thực hiện các thử nghiệm với [[ và đảo ngược mã kết quả của nó. (Trường hợp "bình thường" sẽ trả về 0 để thành công, nhưng có thể bạn đang cố gắng xác minh rằng chuỗi không khớp?)

+0

những thứ đó ... đại diện cho tập lệnh sau $ {1} và trong tập lệnh thực tế của tôi, tôi đã cẩn thận chia tập lệnh và dấu ngoặc vuông của mình bằng một dấu cách. vì vậy tôi không nghĩ rằng đó là vấn đề với điều đó –

+0

không, chức năng của tôi 1 thực sự kiểm tra nếu $ 1 là phù hợp với một số loại biểu thức chính quy.và chức năng của tôi 1 chỉ hoạt động tốt một mình. vì vậy những gì tôi nghĩ là có một số vấn đề với điều kiện trong chức năng chính của tôi –

+0

Ồ, xin lỗi, đã bỏ sót lỗi trong 'main'. Cảm ơn gợi ý. Phân tích cơ bản vẫn còn giữ; '[' không phải là điều bạn nghĩ. – tripleee