Відповіді:
Це перевіряє, що $1
це порожньо, хоча його слід цитувати (ідентично [ -z "$1" ]
). Деякі дуже старі оболонки не обробляють порожні рядки належним чином, тому автори портативних сценаріїв прийняли цей стиль перевірки. Це не було потрібно десятиліттями, але люди все одно роблять це так, тому що люди все ще роблять це так.
[ x$1 = x ]
по - , як і раніше неправильно, але [ "x$1" = x ]
було б для оболонок , які мають проблеми , де $1
є !
або (
чи -n
.... [ "" = "$1" ]
і case $1 in "")
буде також нормально , хоча.
[ -z "$1" ]
і [ "$1" = "" ]
досі не працюють з / bin / sh Solaris 10, колишнім тире-0.5.4.
[ "$1" = "" ]
досі не працює з її /bin/sh
(хоча ви хочете використовувати її /usr/xpg4/bin/sh
там, ні /bin/sh
). тире було зафіксовано з цього приводу в січні 2009 року.
Квадратні дужки вказують на тест , тому [ x$1 = x]
без if
або щось подібне безглуздо, хоча синтаксично добре.
Це призначено для оцінки true, якщо x$1
розширюється на x
, а false - інакше, але оскільки це не цитується, якщо $1
є (наприклад) "hey x", оболонка побачить x = x
, тому ця конструкція все ще не є безпечною.
Мета x = x
перевірки - визначити, чи змінна порожня. Більш поширеним способом зробити це було б просто використовувати лапки:
if [ "$1" = "" ]; then
Оператори тестування Bash -z
і -n
також можуть бути використані, але вони менш стерпні на інші типи оболонок. 1
Причина цитат, або x$1
, полягає в тому, що ліва сторона не розширюється ні до чого, що було б синтаксичною помилкою:
if [ = x ] # No good!
if [ "" = "" ] # Okay.
if [ x = x ] # Also okay.
1. Насправді, це test
може бути окрема утиліта, але більшість оболонок реалізують її як вбудовану; перевірити різницю між which test
і type test
. У GNU / Linux man test
стверджується, що посилається на вбудований, але якщо ви зателефонуєте (наприклад) /usr/bin/test
, ця утиліта, здається, реалізує функції, задокументовані на довільній сторінці, включаючи -z
та -n
.
[ x$1 = x ]
буде також оцінювати як істинне, якщо $1
є, наприклад " -o x"
. Спробуйте sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
. [ x$1 = x ]
помиляється і не має сенсу.
if
щоб використання test
, ви можете використовувати його раніше &&
, ||
або після while
або перевірити результат з допомогою$?
[ x$1 = x ]
Має сенс тільки в zsh
. Це порівнює конкатенацію x
першого аргументу сценарію з x
. Отже [
команда повертає true, якщо $1
вона порожня або не надана.
[ $1 = "" ]
Не буде працювати, тому що, zsh
коли порожня змінна не цитується в контексті списку, вона розширюється взагалі без аргументу замість порожнього аргументу, тому, якщо вони $1
були встановлені чи порожні, [
команда отримала б лише аргументи [
, =
порожній рядок і з ]
чого це не могло мати сенсу. [ -z "$1" ]
або [ "$1" = "" ]
буде добре, хоча як у оболонках POSIX.
У снарядах Борна / POSIX [ x$1 = x ]
не має сенсу. Ось оператор split + glob якось застосував до конкатенації x
та першого аргументу сценарію, сподіваючись, що результат і =
та x
, і ]
складе дійсний тестовий вираз для [
команди.
Наприклад, якщо сценарій був переданий один " = x -o x ="
аргумент, [
отримають ці аргументи: [
, x
, =
, x
, -o
, x
, =
, x
, ]
, що [
б зрозуміти , як порівняння x
з x
і x
з x
і повертає істину.
Якщо $1
були "* *"
, то оболонка буде перейти до [
команді список файлів в поточному каталозі, ім'я якого починається з x
(розширенням Глоби в x*
), то перелік не-приховані файли (розширення *
) ... що [
навряд чи зможемо щоб не було сенсу. Єдині випадки, коли це може зробити щось розумне, це якщо $1
він не містить символів підстановки чи порожніх символів.
Тепер те, що ви іноді знаходите, такий код:
[ "x$1" = x ]
Це використовується для перевірки, чи $1
порожній або невідомий.
Нормальний спосіб перевірити наявність порожньої чи невстановленої змінної:
[ -z "$1" ]
Але це не вдається для деяких значень, $1
як =
у деяких (не-POSIX) [
реалізаціях, таких як вбудований в оболонці Bourne, як знайдено в /bin/sh
Solaris 10 і раніше, або деяких старих версіях dash
(до 0,5.4) або sh
деяких BSD.
Це тому , що [
бачить [
, -z
, =
, ]
і скаржиться на відсутні аргументи =
бінарного оператора замість розуміння його як -z
унарний оператор застосовується до =
рядку.
Аналогічно, відбувається [ "$1" = "" ]
збій для деяких реалізацій [
if $1
є !
або (
.
У цих оболонках / [
реалізаціях:
[ "x$1" = x ]
завжди є дійсним тестом незалежно від значення $1
, тому:
[ "" = "$1" ]
і:
[ -z "${1:+x}" ]
і
case $1 in "") ...; esac
Звичайно, якщо ви хочете перевірити, чи не наводиться аргумент, ви зробите:
[ "$#" -eq 0 ]
Тобто ви перевіряєте кількість аргументів, переданих скрипту.
Зверніть увагу , що в даний час, [ -z "$var" ]
чітко визначено POSIX і не може потерпіти невдачу в узгоджуються [
реалізації (і bash
«s [
це і було протягом десятиліть). Таким чином, ви повинні мати можливість покластися на це в POSIX sh або bash
скриптах.
x$1
є об'єднанням двох рядків x
і, $1
якщо $ 1 порожній, x $ 1 дорівнює x, і [x $ 1 = x] буде істинним. x = y
використовується для порівняння рядків у ш
x$1
, не котирується, тому розщеплення та глобалізація виконується на тих.
[ x$1 = x ]
вірно, якщо він $1
не встановлений / null / порожній чи ні.
Спробуйте себе:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
і
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
[ x$1 = x ]
також вірно, якщо $1
є, наприклад " -o x"
. Спробуйте sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
. [ x$1 = x ]
помиляється і не має сенсу.