2015-07-01 31 views
6

Spodziewam się użyć poniższej zmiennej w moim skrypcie bash, ale w przypadku, gdy jest pusta lub zerowa, najlepiej będzie jak sobie z nią poradzić i wyjść ze skryptu.Skrypt powłoki - zamykanie skryptu, jeśli zmienna jest pusta lub pusta

tag=$1 

Widzę odpowiedzi z "set -u". Wiem, że to zadziała, ale czy jest to dobre dla środowiska produkcyjnego?

+1

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29 –

+0

Jeżeli zmienna składający whitespaces tylko jak to: 'var =” „' uznać pusty czy nie? –

+0

tak, zmienna składająca się z białych znaków, uznana za pustą. zasadniczo, myślę, aby umieścić czek, jak gdyby [[! -z "$ {Tag}" && "$ {Tag}"! = '']] za to. –

Odpowiedz

17

Istnieje wbudowany operator, który wymaga ustawienia zmiennej. Spowoduje to wyjście skryptu, jeśli tak nie jest.

tag=${1?Need a value} 

Zwykle jest to używane z : no-op blisko początku skryptu.

: ${1?Need a value} 

Konflikt "niewzruszony lub pusty" jest nieco inny. Nie ma podobnej konstrukcji do wyjścia na pustą, ale ustawioną wartość, ale można łatwo użyć odpowiedniej składni ${var:-default}, która rozwija się do $var, jeśli jest ustawiona i niepustą, i default w przeciwnym razie. Istnieje również ${var-default}, który produkuje tylko default, jeśli zmienna jest poprawnie rozbita.

Może to być szczególnie przydatne, gdy chcesz używać set -u ale trzeba uporać się z możliwie wyłączonym zmiennej:

case ${var-} in '') echo "$0: Need a value in var" >&2; exit 1;; esac 

ja nieco wolą case nad if [ "${var-}" = '' ], głównie dlatego, że ratuje mnie od konieczności zawijania podwójne cytaty około ${var-} i brzydki przypadek wartości w $var, który zostanie zinterpretowany jako opcja do [ i wyświetli komunikat o błędzie, gdy najmniej się tego spodziewasz. (Bash, [[ nie ma tych problemów, ale ja wolę trzymać się powłoki POSIX, kiedy tylko mogę.)

10

Jeśli chcesz sprawdzić, czy zmienna jest niepusty, można to zrobić:

if [ -z "$tag" ]; then 
    exit 1 
fi 

z podręcznika dla test:

-z STRING

długość od STRING wynosi zero

Biorąc pod uwagę, że używasz p argumenty ositional dla skryptu, można również przetestować liczbę otrzymywanych argumentów, patrząc na $#.

+2

Potrzebujesz cytatów dookoła '" $ tag "' lub to zawiedzie w pustym ciągu (spróbuj i zobacz). –

+0

@EtanReisner dzięki! zaktualizowano –

1

Nie jestem pewien, czy chcesz, aby wykryć, czy zmienna jest unset lub empty. To są 2 różne rzeczy.Konkretnie, zmienna może być ustawiona ale być puste:

$ var="" 
$ if [ -z "$var" ]; then echo empty; fi 
$ empty 

To samo dzieje się tutaj:

#!/usr/bin/env bash 

set -u 
echo $1 

Test:

$ ./test.sh 
./test.sh: line 4: $1: unbound variable 
$ ./test.sh "" 

$ 

Albo tutaj:

#!/usr/bin/env bash 

tag=${1?Need a value} 
echo $tag 

Test:

$ ./se.sh 
./se.sh: line 3: 1: Need a value 
$ ./se.sh "" 

$ 

Inne plakaty przedstawiają poprawne sposoby wykrywania nieuzbrojonej i pustej zmiennej. Osobiście lubię ten sposób wykrywania pustych i wyłączenie zmiennych:

#!/usr/bin/env bash 

if [ "$1"A = A ] 
then 
    echo variable is empty or unset 
fi 

Test:

$ ./empty.sh "" 
variable is empty or unset 
$ ./empty.sh 
variable is empty or unset 
$ ./empty.sh 1 
$ 
+1

Metoda "$ 1" A "jest niepotrzebna w przypadku jakiejkolwiek zdalnie nowoczesnej implementacji powłoki. To był hak konieczny dla starych powłok, które nie mogły obsługiwać jawnie pustych argumentów dla polecenia 'test'. '[" $ 1 "=" "]' może obsłużyć pusty/unset '$ 1' równie dobrze. – chepner

+0

Nie jest to konieczne, ale nadal, po prostu lubię. To kwestia osobistych preferencji. –

0

Użyj dopasowania do wykrycia, jeśli wartość składa się wyłącznie z białych znaków wzorca:

pattern=$'*(|\t)' 
if [[ $1 = $pattern ]]; then 
    echo "First parameter has no non-whitespace characters" 
    exit 1 
fi 

$'...' cytowanie ułatwia dodanie karty do ciągu znaków. Rozszerzony wzór *(...) dopasowuje 0 lub więcej wzorców w nawiasach (podobnie do regex (|\t)*). Wzorzec jest przypisany do zmiennej, ponieważ = dokonuje dokładnego dopasowywania ciągów znaków, jeśli jakakolwiek część jej prawego operandu jest cytowana, dlatego wcześniej wykonujemy cytowanie, aby ułatwić ustawienie wartości.

+0

Aby to działało, musisz włączyć rozszerzone globowanie, prawda? – tripleee

+0

Może. Nowsze wersje 'bash' (4.2 i późniejsze?) Tymczasowo zamieniają rozszerzony globbing wewnątrz' [[...]] ', więc nie ma potrzeby tego robić jawnie. W przeciwnym razie, tak, 'shopt -s extglob' jest potrzebny. – chepner

1

Podobało mi się, jak Perl używa "umrzeć" i łatwo jest zrobić coś podobnego w powłoce.

# Print (optional) error message and exit 
# Usage: die [[msg] exit_status] 
die() { 
    [[ -n "$1" ]] && echo "$1" 
    [[ -n "$2" ]] && exit $2 || exit 1 
} 

[[ -n "$tag" ]] || die "Need a tag argument. Use $0 --help for details" 

Zakłada ciachnięcie lub Körne powłoki, ale można je przekształcić w klasycznym przenoszonej powłoki zmieniając [[]] do [].

0

Poniższy test zapewnia, że ​​zmienna ma wartość Null lub ma przypisaną wartość. Podwójne cytaty są bardzo ważne i muszą być użyte!

VAL= # Creates a NULL variable 
if [[ -z "$VAL" && "$VAL" = ’’ ]] 
then 
echo "The VAL variable is NULL" 
fi 
or 
VAL=25 
if [[ ! -z "$VAL" && "$VAL" != ’’ ]] 
then 
echo "The VAL variable is NOT NULL" 
fi 
Powiązane problemy