Vraag Unset gebruiken versus een variabele instellen om leeg te maken


Ik schrijf momenteel een bash-testraamwerk, waarbij in een testfunctie, beide standaard bash-tests ([[) evenals vooraf gedefinieerde matchers kunnen worden gebruikt. Matchers zijn wrappers naar '[[' en naast het retourneren van een retourcode stelt u een zinvol bericht in waarin staat wat er van u werd verwacht.

Voorbeeld:

string_equals() {
    if [[ ! $1 = $2 ]]; then
            error_message="Expected '$1' to be '$2'."

            return 1
    fi
}

Dus wanneer een matcher wordt gebruikt en deze mislukt, pas dan wordt een error_message ingesteld.

Nu, op een bepaald moment later, test ik of de tests geslaagd zijn. Als het gelukt is, print ik de verwachting in groen, als het rood is mislukt.

Bovendien kan er een error_message zijn ingesteld, dus ik test of er een bericht bestaat, druk het af en schakel het vervolgens uit (omdat de volgende test mogelijk geen error_message):

if [[ $error_message ]]; then
    printf '%s\n' "$error_message"

    unset -v error_message
fi

Nu is mijn vraag, of het beter is om de variabele uit te schakelen, of om hem gewoon in te stellen op '', zoals

error_message=''

Welke is beter? Maakt het echt een verschil? Of moet ik misschien een extra markering gebruiken om aan te geven dat het bericht is ingesteld?


83
2017-09-04 11:37


oorsprong


antwoorden:


Meestal zie je geen verschil, tenzij je gebruikt set -u:

/home/user1> var=""
/home/user1> echo $var

/home/user1> set -u
/home/user1> echo $var

/home/user1> unset var
/home/user1> echo $var
-bash: var: unbound variable

Dus eigenlijk hangt het ervan af hoe je de variabele gaat testen.

Ik zal hieraan toevoegen dat mijn voorkeursmethode om te testen of deze is ingesteld, is:

[[ -n $var ]]  # True if the length of $var is non-zero

of

[[ -z $var ]]  # True if zero length

117
2017-09-04 12:54



Zoals gezegd, is het gebruik van Unset ook anders met arrays

$ foo=(4 5 6)

$ foo[2]=

$ echo ${#foo[*]}
3

$ unset foo[2]

$ echo ${#foo[*]}
2

13
2017-10-18 16:52



Dus door de array-index 2 uit te schakelen, verwijdert u in feite dat element in de array en verkleint u de array-afmeting (?).

Ik heb mijn eigen test gemaakt ..

foo=(5 6 8)
echo ${#foo[*]}
unset foo
echo ${#foo[*]}

Wat resulteert in..

3
0

Dus gewoon om te verduidelijken dat het uitschakelen van de hele array het in feite volledig zal verwijderen.


0
2018-04-12 07:52



Op basis van de bovenstaande opmerkingen, hier is een eenvoudige test:

isunset() { [[ "${!1}" != 'x' ]] && [[ "${!1-x}" == 'x' ]] && echo 1; }
isset()   { [ -z "$(isunset "$1")" ] && echo 1; }

Voorbeeld:

$ unset foo; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's unset
$ foo=     ; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's set
$ foo=bar  ; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's set

0
2017-07-19 14:37