Thử nghiệm -n && echo không trống Đó có phải là hành vi dự kiến?


7

Khi tôi thực hiện dòng sau

test -n && echo not empty

nó in "không trống". Điều này xảy ra khi bạn có một biến trống và kiểm tra độ không trống trong khi quên trích dẫn giá trị:

VAR=
test -n  $VAR  && echo wrong 1
test -n "$VAR" && echo wrong 2

Đây có phải là hành vi dự kiến?

Câu trả lời:


9

Vâng, đây là hành vi dự kiến. Khi chỉ có một đối số được truyền vào test, kiểm tra độ dài được thực hiện. Từ man bash:

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

0 đối số: Biểu thức là sai.

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

Đó là, về cơ bản nó là tương đương test foo, nhưng sử dụng -nnhư là chuỗi.


3

test -nprima facie không đúng, vì -nyêu cầu một đối số. Tôi tin rằng một số triển khai lịch sử đã coi nó như một lỗi cú pháp (và trả về trạng thái khác không). Tuy nhiên, trong tất cả các hệ vỏ bạn có thể gặp phải trong thế kỷ 21, hành vi được xác định rõ (theo POSIX , theo thông lệ hiện tại): nếu testchỉ có một đối số, thì đó là sự thật nếu và chỉ khi đối số đó không phải là -trống.

Lưu ý rằng nếu bạn bỏ qua dấu ngoặc kép, kết quả kiểm tra có thể là sai đối với một số giá trị không trống của $VAR. Nó thậm chí có thể in ra một thông báo lỗi nếu có các ký tự toàn cầu $VAR.

VAR='foo -a -z bar'; test -n $VAR || echo "true... and false is false"
VAR='= n-'; test -n $VAR || echo "this is an equality test"
VAR='*'; test -n $VAR || echo "you may or may not see this depending on what files are in the current directory"

test -z $VAR cũng bị hỏng tương tự.

Ksh, bash và zsh có [[ … ]]cấu trúc có điều kiện bắt chước truyền thống test[tiện ích. Không giống như [, đó là một tiện ích bên ngoài hoặc là một tiện ích tích hợp được phân tích cú pháp như một, [[ … ]]là một phần của cú pháp shell. Không có từ tách hoặc Globing bên trong [[ … ]]. [[ -n $VAR ]]vẫn ổn (miễn là bạn không quan tâm rằng tập lệnh của bạn sẽ không chạy dưới các shell khác như tro).


1

Kiểm tra cũng [[ ... ]]không chịu hành vi này:

[[ -n $VAR ]] && echo wrong 3
[[ -n "$VAR" ]] && echo wrong 4

Thú vị và đáng để ý, nhưng "đau khổ" có lẽ không phải là từ đúng ở đây ... [[ ... ]]không giống như [ ... ]biểu hiện hành vi tương tự testvà là chức năng được đề cập trong man bash... Trong [[ ... ]]biến không cần phải là (. ví dụ như một "$ trích dẫn" để được công nhận là một biến arg đến [[) ... Điều này boils xuống một trường hợp đơn giản của: biến không được trích dẫn và nó cần phải có được.
Peter.O


0

Có vẻ như khi bạn làm như sau:

VAR=
test -n $VAR && echo helloworld

Nó đối xử với nó như thể tranh luận không có ở đó:

test -n && echo helloworld

Và, vì một số lý do, khi đối số không được cung cấp, nó luôn chạy lệnh sau đó (tức là nó hiển thị hellowworld). Tôi đã thử điều này trên một toán tử khác và nó cũng làm như vậy:

FILENAME=
test -f $FILENAME && echo helloworld

Tôi nghĩ rằng nếu bạn muốn có hành vi mong đợi, bạn phải trích dẫn lập luận:

VAR=
test -n "$VAR" && echo helloworld
FILE=
test -f "$FILE" && echo helloworld

Các kết quả trên không mang lại thông điệp vang vọng đến màn hình.

Như là hành vi dự kiến? Tôi không thể tìm thấy nó trong tài liệu ở bất cứ đâu, nhưng, nó có vẻ khá tái tạo và nhất quán.

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.