Почему [[...]] не работает, когда скрипт вызывается с помощью sh, а [...] работает всегда? - PullRequest
3 голосов
/ 10 ноября 2009

Скрипт test.sh:

#!/bin/bash
if [[ $# -eq 0 ]]; then
  echo "no arg"
else
  echo "have arg"
fi

Когда я запустил его как

./test.sh

он сказал "нет аргумента", что и ожидалось, но если я запусту его как

sh ./test.sh

он печатает "иметь аргумент", но если вы печатаете $ #, в обоих случаях он равен нулю.

Однако, скрипт ниже

#!/bin/bash
if [ $# -eq 0 ]; then
  echo "no arg"
else
  echo "have arg"
fi

печатает «без аргументов» в обоих случаях.

Может кто-нибудь объяснить это? Почему [[ ... ]] интерпретирует $# иначе, чем [ ... ]?

Объяснения, которые я прочитал о [[ ... ]], недостаточно ясны по этому поводу.

Ответы [ 2 ]

2 голосов
/ 10 ноября 2009

/ bin / sh часто отличается от интерпретатора оболочки, чем bash. В моей системе Ubuntu это символическая ссылка на тире. Разные оболочки имеют разный синтаксис.

[ foo ] и test foo эквивалентны как в bash, так и в dash.

[[ foo ]] - это выражение bash, похожее на [ ] тесты, но с некоторыми отличиями, отмеченными в man bash.

У Dash нет команды [[, которая приводит к коду ошибки-выхода и выполнению ветви else.

   [[ expression ]]
          Return a status of 0 or 1 depending on  the  evaluation  of  the
          conditional  expression expression.  Expressions are composed of
          the primaries described  below  under  CONDITIONAL  EXPRESSIONS.
          Word  splitting  and pathname expansion are not performed on the
          words between the [[ and  ]];  tilde  expansion,  parameter  and
          variable  expansion, arithmetic expansion, command substitution,
          process substitution, and quote removal are  performed.   Condi‐
          tional operators such as -f must be unquoted to be recognized as
          primaries.

          When the == and != operators are used, the string to  the  right
          of the operator is considered a pattern and matched according to
          the rules described below under Pattern Matching.  If the  shell
          option  nocasematch  is  enabled, the match is performed without
          regard to the case of alphabetic characters.  The  return  value
          is  0 if the string matches (==) or does not match (!=) the pat‐
          tern, and 1 otherwise.  Any part of the pattern may be quoted to
          force it to be matched as a string.

          An  additional  binary operator, =~, is available, with the same
          precedence as == and !=.  When it is used,  the  string  to  the
          right  of the operator is considered an extended regular expres‐
          sion and matched accordingly (as in regex(3)).  The return value
          is 0 if the string matches the pattern, and 1 otherwise.  If the
          regular expression is syntactically incorrect,  the  conditional
          expression's return value is 2.  If the shell option nocasematch
          is enabled, the match is performed without regard to the case of
          alphabetic characters.  Any part of the pattern may be quoted to
          force it to be matched  as  a  string.   Substrings  matched  by
          parenthesized  subexpressions  within the regular expression are
          saved in  the  array  variable  BASH_REMATCH.   The  element  of
          BASH_REMATCH  with index 0 is the portion of the string matching
          the entire regular expression.  The element of BASH_REMATCH with
          index  n is the portion of the string matching the nth parenthe‐
          sized subexpression.
1 голос
/ 10 ноября 2009

В моем случае (Ubuntu 9.04) я также вижу следующую строку ошибки над строкой "иметь аргумент":

. / Test.sh: 6: [[: не найдено

И действительно, так и должно быть; / bin / sh является символической ссылкой на 'dash', а не 'bash'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...