Làm thế nào để tìm xem một biến có trống hay không trong Bash


262

Làm thế nào tôi có thể kiểm tra nếu một biến trống trong Bash?


2
Những loại kịch bản shell? * nix?
TJ Crowder

8
kịch bản bash shell
Cây



Câu trả lời:


383

Trong Bash ít nhất các lệnh sau kiểm tra nếu $ var trống :

if [[ -z "$var" ]]; then
   # Do what you want
fi

Lệnh man testlà bạn của bạn.


62
dấu ngoặc vuông là vô dụng ở đây. nó có thể đơn giản [-z "$ var"] hoặc thậm chí imho dễ dàng hơn nếu test -z "var" .. anyway +1 :)
Luca Borrione

2
dấu ngoặc kép không phải là vô ích, nếu tôi không bao gồm thì tôi không ./test.ksh[8]: test: argument expectedhiểu lý do nhưng dấu ngoặc đơn không hoạt động nhưng cái kép có nó.
gahlot.jagss

8
@LucaBorrione Tôi nghĩ bạn có ý nghĩa if test -z "$var", phải không?
neu242

1
Chỉ cần một nhận xét bổ sung cho một tình huống cụ thể không được đề cập trực tiếp trong câu hỏi: nếu biến không được đặt và set -utùy chọn đã được kích hoạt, thử nghiệm này sẽ thất bại với unbound variable. Trong trường hợp này, bạn có thể thích giải pháp của @ alexli.
anol

3
@LucaBorrione Chỉ là một ghi chú bên lề: "[[" có thể được xem là "không bao giờ vô dụng"; như sử dụng "[[" có một số lợi thế so với "[" (xem stackoverflow.com/questions/669452/iêu chẳng hạn)
GhostCat

107

Giả sử Bash:

var=""

if [ -n "$var" ]; then
    echo "not empty"
else
    echo "empty"
fi

9
Câu trả lời trực tiếp hơn là -z:[[ -z "$an_unset_or_empty_var" ]] && echo empty
glenn jackman

4
@glenn jackman: bình luận tốt; đúng -zlà gần với những gì được hỏi Jay đã đưa ra câu trả lời này vì vậy tôi sẽ không cập nhật thông tin của mình và để nguyên như vậy.
BarsheD

48

Tôi cũng đã thấy

if [ "x$variable" = "x" ]; then ...

đó rõ ràng là rất mạnh mẽ và vỏ độc lập.

Ngoài ra, có một sự khác biệt giữa "trống" và "không đặt". Xem Cách nhận biết nếu một chuỗi không được xác định trong tập lệnh shell Bash .


Có vẻ lạ đối với tôi. Bạn có thể vui lòng giải thích giải pháp này. Cảm ơn bạn.
guettli

2
@guettli: Nếu $variabletrống, thì chuỗi bên trái của toán tử so sánh chỉ trở thành x, sau đó bằng với chuỗi bên phải của toán tử. [ x = x ]là "đúng", vì vậy trong thực tế kiểm tra này có $variabletrống hay không. Như một sự bổ sung (3 năm rưỡi sau thực tế :-)) Tôi sẽ không bao giờ sử dụng cái này vì -ztôi có thể muốn một cách rõ ràng hơn, nhưng tôi muốn thêm câu trả lời này vì phương pháp này thường được nhìn thấy "trong tự nhiên"; có lẽ được viết theo cách này trên mục đích bởi những người đã có kinh nghiệm khác với tôi.
Daniel Andersson

30
if [ ${foo:+1} ]
then
    echo "yes"
fi

in yesnếu biến được đặt. ${foo:+1}sẽ trả về 1 khi biến được đặt, nếu không nó sẽ trả về chuỗi rỗng.


2
Mặc dù không được đề cập trong câu hỏi, một lợi thế quan trọng của câu trả lời này là nó hoạt động ngay cả khi biến không được xác định và set -utùy chọn ( nounset) được kích hoạt. Hầu như tất cả các câu trả lời khác cho câu hỏi này sẽ thất bại unbound variabletrong trường hợp này.
anol

Đây :+ký hiệu cũng hữu ích cho tình huống mà bạn có thông số dòng lệnh tùy chọn mà bạn đã xác định với các biến số tùy chọn. myprogram ${INFILE:+--in=$INFILE} ${OUTFILE:+--out=$OUTFILE}
Alan Porter


10
[ "$variable" ] || echo empty
: ${variable="value_to_set_if_unset"}

Cách tuyệt vời để mặc định var, cộng với 1
ehime

@ehime để tạo một giá trị mặc định bạn sẽ sử dụng${variable:-default_value}
warvariuc

Đây là một cách nhanh chóng để kiểm tra tính hợp lệ của mục nhập biến và thoát nếu không được đặt: [ "$variable" ] || exit
Marcel Sonderegger

8

Điều này sẽ trả về truenếu một biến không được đặt hoặc được đặt thành chuỗi trống ("").

if [ -z "$MyVar" ]
then
   echo "The variable MyVar has nothing in it."
elif ! [ -z "$MyVar" ]
then
   echo "The variable MyVar has something in it."
fi

3
Tại sao bạn sẽ sử dụng elif !thay vì else?
ZiggyTheroulette

1
Chỉ cần phân biệt giữa hai câu lệnh, nghĩa là sử dụng ! [ -z "$MyVar" ]có nghĩa là biến đó sẽ một cái gì đó trong đó. Nhưng lý tưởng nhất là người ta sẽ sử dụng else.
3kstc

6

Câu hỏi hỏi làm thế nào để kiểm tra xem một biến có phải là một chuỗi rỗng hay không và câu trả lời tốt nhất đã được đưa ra cho điều đó.

Nhưng tôi đã hạ cánh ở đây sau một thời gian thông qua lập trình trong PHP và tôi thực sự đang tìm kiếm một kiểm tra giống như hàm rỗng trong PHP hoạt động trong trình bao Bash.

Sau khi đọc các câu trả lời tôi nhận ra rằng tôi đã không suy nghĩ đúng đắn về Bash, nhưng dù sao trong thời điểm đó, một hàm như trống trong PHP sẽ rất tiện trong mã Bash của tôi.

Vì tôi nghĩ điều này có thể xảy ra với những người khác, tôi quyết định chuyển đổi hàm rỗng PHP trong Bash.

Theo hướng dẫn sử dụng PHP :

một biến được coi là trống nếu nó không tồn tại hoặc nếu giá trị của nó là một trong những điều sau đây:

  • "" (một chuỗi trống)
  • 0 (0 dưới dạng số nguyên)
  • 0,0 (0 dưới dạng nổi)
  • "0" (0 dưới dạng chuỗi)
  • một mảng trống
  • một biến được khai báo, nhưng không có giá trị

Tất nhiên các trường hợp nullsai không thể được chuyển đổi trong bash, vì vậy chúng được bỏ qua.

function empty
{
    local var="$1"

    # Return true if:
    # 1.    var is a null string ("" as empty string)
    # 2.    a non set variable is passed
    # 3.    a declared variable or array but without a value is passed
    # 4.    an empty array is passed
    if test -z "$var"
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is zero (0 as an integer or "0" as a string)
    elif [ "$var" == 0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is 0.0 (0 as a float)
    elif [ "$var" == 0.0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return
    fi

    [[ $( echo "" ) ]]
}



Ví dụ về cách sử dụng:

if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



Bản trình diễn:
Đoạn mã sau:

#!/bin/bash

vars=(
    ""
    0
    0.0
    "0"
    1
    "string"
    " "
)

for (( i=0; i<${#vars[@]}; i++ ))
do
    var="${vars[$i]}"

    if empty "${var}"
        then
            what="empty"
        else
            what="not empty"
    fi
    echo "VAR \"$var\" is $what"
done

exit

đầu ra:

VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty

Phải nói rằng trong logic Bash, các kiểm tra về số 0 trong hàm này có thể gây ra các vấn đề phụ, bất kỳ ai sử dụng hàm này nên đánh giá rủi ro này và có thể quyết định cắt bỏ các kiểm tra đó chỉ để lại kiểm tra đầu tiên.


2

Bạn có thể muốn phân biệt giữa các biến unset và biến được đặt và trống:

is_empty() {
    local var_name="$1"
    local var_value="${!var_name}"
    if [[ -v "$var_name" ]]; then
       if [[ -n "$var_value" ]]; then
         echo "set and non-empty"
       else
         echo "set and empty"
       fi
    else
       echo "unset"
    fi
}

str="foo"
empty=""
is_empty str
is_empty empty
is_empty none

Kết quả:

set and non-empty
set and empty
unset

BTW, tôi khuyên bạn nên sử dụng set -usẽ gây ra lỗi khi đọc các biến không đặt, điều này có thể cứu bạn khỏi các thảm họa như

rm -rf $dir

Bạn có thể đọc về điều này và các thực tiễn tốt nhất khác cho "chế độ nghiêm ngặt" tại đây .


Cảm ơn đã tham khảo chế độ nghiêm ngặt!
paulcm

1

Để kiểm tra nếu biến v không được đặt

if [ "$v" == "" ]; then
   echo "v not set"
fi
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.