Відповіді:
Деякі історичні оболонки реалізували дуже простий аналізатор, який може заплутатися в таких речах, як, наприклад, [ -n = "" ]
перший операнд, =
схожий на оператора, і розбере це як [ -n = ]
або викликає синтаксичну помилку. В результаті [ "x$1" = x"" ]
, x
префікс гарантує, що він x"$1"
не може бути схожим на оператора, і тому єдиний спосіб оболонки проаналізувати цей тест - це трактуватись =
як двійковий оператор.
Усі сучасні оболонки, і навіть більшість старих снарядів, які все ще працюють, дотримуються правил POSIX, які передбачають, що всі тестові вирази розміром до 4 слів будуть правильно розібрані. Це [ -z "$1" ]
правильний спосіб тестування, якщо $1
він порожній , і [ "$x" = "$y" ]
це правильний спосіб перевірити рівність двох змінних.
Навіть деякі поточні оболонки можуть плутатись із більш тривалими виразами, а декілька виразів насправді неоднозначні, тому уникайте використання операторів -a
та -o
для побудови довших булевих тестів, а замість цього використовуйте окремі виклики [
та власні &&
та ||
булеві оператори оболонки .
[ -z "$1" ]
це правильний спосіб тестування, якщо $1
він порожній . sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'
- обидва повертають 0, але у другому випадку $1
не може бути порожнім, оскільки його немає.
Згідно з http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html , -z
тест є небезпечним у деяких реалізаціях , імовірно, коли "цікаві" рядки на кшталт "-o a=a"
тестуються.
Вищеописані тести також спричинить помилку, якщо ви працюєте з "set -u" або "set -o nounset"
Більш стабільним способом перевірити порожню змінну буде використання розширення параметрів :
MYVAR = $ {MYVAR: - "Погане значення"}
Цей метод працює для традиційної оболонки бурна, а також ksh і bash.
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
=
проти -z
, а тепер як.
sh
на деяких комерційних Unice, все ще мають проблему. Детальніше дивіться тут .