Kiểm tra nếu một biến trống trong tập lệnh shell


27

Tôi đã thấy kỹ thuật sau đây được sử dụng nhiều lần trên nhiều shell khác nhau, để kiểm tra xem một biến có trống không:

if [ "x$1" = "x" ]; then 
    # Variable is empty
fi

Có bất kỳ lợi thế về việc sử dụng này hơn kinh điển hơn if [ -z "$1" ]? Nó có thể là một vấn đề di động?

Câu trả lời:


17

Một số shell lịch sử đã triển khai một trình phân tích cú pháp rất đơn giản có thể bị nhầm lẫn bởi những thứ như [ -n = "" ]toán hạng đầu tiên =trông giống như một toán tử và sẽ phân tích cái này như là [ -n = ]hoặc gây ra lỗi cú pháp. Trong [ "x$1" = x"" ], xtiền tố đảm bảo rằng x"$1"không thể trông giống như một toán tử, và vì vậy cách duy nhất mà shell có thể phân tích kiểm tra này là bằng cách xử lý =như một toán tử nhị phân.

Tất cả các trình bao hiện đại và thậm chí hầu hết các trình bao cũ hơn vẫn còn hoạt động, tuân theo các quy tắc POSIX bắt buộc tất cả các biểu thức kiểm tra có tối đa 4 từ được phân tích cú pháp chính xác. Vì vậy, [ -z "$1" ]một cách thích hợp để kiểm tra nếu $1trống[ "$x" = "$y" ]là một cách thích hợp để kiểm tra sự bằng nhau của hai biến.

Ngay cả một số shell hiện tại có thể bị nhầm lẫn với các biểu thức dài hơn và một vài biểu thức thực sự mơ hồ, do đó, tránh sử dụng các toán tử -a-ođể xây dựng các thử nghiệm boolean dài hơn, và thay vào đó sử dụng các lệnh gọi [riêng &&||các toán tử boolean của shell .


3
Đó không chỉ là vỏ ốc lịch sử . Một số ksh88 dựa shtrên một số Unice thương mại vẫn có vấn đề. Xem ở đây để biết chi tiết.
Stéphane Chazelas

Tuyên bố này không chính xác: [ -z "$1" ]là một cách kiểm tra thích hợp nếu $1trống . sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'- cả hai trả về 0, nhưng trong trường hợp thứ hai $1không thể để trống vì nó không tồn tại.
mikeerv


3

Các bài kiểm tra trên cũng sẽ gây ra lỗi nếu bạn chạy với "set -u" hoặc "set -o nounset"

Một cách ổn định hơn để kiểm tra một biến trống sẽ là sử dụng mở rộng tham số :

MYVAR = $ {MYVAR: - "Giá trị xấu"}

Phương pháp này hoạt động cho vỏ bourne truyền thống, cũng như ksh và bash.


2
Tôi tin rằng điều này được viết là -> M = $ {M: - "Giá trị xấu"}
Gyan

0
    function isBlank {
 valueNoSpaces=$(echo "$@" | tr -d ' ')

 if [  "$valueNoSpaces" == null ] || [ -z "$valueNoSpaces" ] 
 then
       echo true ;
 else
       echo ""  ;
 fi
}

#Test
if [ $(isBlank "      ") ] 
then
    echo "isBlank \"      \" : it's blank"
else
    echo " isBlank \"      \": it is not blank"
fi

if [ $(isBlank "abc") ] 

then
    echo "isBlank \"abc\" : it's blank"
else
    echo "isBlank \"abc\" :it is not blank"
fi

if [ $(isBlank null) ] 
then
      echo "isBlank null : it's blank"
else
    echo "isBlank null : it is not blank"
fi

if [ $(isBlank "") ] 
then
    echo "isBlank \"\" : it's blank"
else
    echo "isBlank \"\" : it is not blank"
fi

#Result
isBlank "      " : it's blank

isBlank "abc" :it is not blank

isBlank null : it's blank

isBlank "" : it's blank

3
Chào! Tôi không chắc làm thế nào điều này trả lời câu hỏi, mà hỏi tại sao nên sử dụng =so với -z, bây giờ làm thế nào.
dhag
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.