Відмінності в поведінці
Деякі відмінності на Bash 4.3.11:
Розширення POSIX проти Bash:
регулярна команда проти магії
[ - це лише звичайна команда зі дивним іменем.
]це лише аргумент, [який запобігає використанню подальших аргументів.
Ubuntu 16.04 насправді має виконуваний файл, який /usr/bin/[надається coreutils , але вбудована версія bash має перевагу.
Ніщо не змінюється так, як Bash розбирає команду.
Зокрема, <це перенаправлення &&та ||об'єднання декількох команд, ( )генерування підшаровок, якщо не уникнути \, і розширення слова відбувається як завжди.
[[ X ]]являє собою єдину конструкцію, яка робить Xмагічний розбір. <, &&, ||І ()розглядаються спеціально, і правила розбиття на слова різні.
Існують також подальші відмінності, як =і =~.
В Bashese: [це вбудована команда і [[є ключовим словом: /ubuntu/445749/whats-the-difference-between-shell-builtin-and-shell-keyword
<
&& і ||
[[ a = a && b = b ]]: вірно, логічно і
[ a = a && b = b ]: помилка синтаксису, &&аналізується як роздільник команд ANDcmd1 && cmd2
[ a = a -a b = b ]: еквівалент, але застарілий POSIX³
[ a = a ] && [ b = b ]: POSIX та надійний еквівалент
(
[[ (a = a || a = b) && a = b ]]: помилковий
[ ( a = a ) ]: синтаксична помилка, ()інтерпретується як піддіаграма
[ \( a = a -o a = b \) -a a = b ]: еквівалент, але ()застаріло через POSIX
{ [ a = a ] || [ a = b ]; } && [ a = b ] POSIX еквівалент⁵
розбиття слів і генерація імен файлів у розширеннях (split + glob)
x='a b'; [[ $x = 'a b' ]]: правда, цитати не потрібні
x='a b'; [ $x = 'a b' ]: синтаксична помилка, поширюється на [ a b = 'a b' ]
x='*'; [ $x = 'a b' ]: помилка синтаксису, якщо в поточному каталозі є більше одного файлу.
x='a b'; [ "$x" = 'a b' ]: POSIX еквівалент
=
[[ ab = a? ]]: вірно, тому що це відповідає узгодженню ( * ? [є магією). Не поширюється на файли у поточному каталозі.
[ ab = a? ]: a?глобус розширюється. Так може бути правдою чи помилкою залежно від файлів у поточному каталозі.
[ ab = a\? ]: хибне, а не глобальне розширення
=і ==однакові в обох [і [[, але ==є розширенням Bash.
case ab in (a?) echo match; esac: POSIX еквівалент
[[ ab =~ 'ab?' ]]: false⁴, втрачає магію с ''
[[ ab? =~ 'ab?' ]]: правда
=~
[[ ab =~ ab? ]]: вірно, POSIX розширений матч регулярного вираження , ?не розширюється глобально
[ a =~ a ]: синтаксична помилка. Немає еквіваленту баш.
printf 'ab\n' | grep -Eq 'ab?': POSIX-еквівалент (лише дані для одного рядка)
awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?': POSIX еквівалент.
Рекомендація : завжди використовуйте [].
Існують POSIX-еквіваленти для кожної [[ ]]конструкції, яку я бачив.
Якщо ви використовуєте [[ ]]:
- втрачають портативність
- змусити читача дізнатися тонкощі іншого розширення баш.
[це лише звичайна команда зі дивним іменем, ніякої спеціальної семантики не задіяно.
¹ Натхненний еквівалентною [[...]]конструкцією в оболонці Корна
², але не вдається для деяких значень aабо b(як +або index) і робить числове порівняння, якщо aі bвиглядає як десяткові цілі числа. expr "x$a" '<' "x$b"працює навколо обох.
³, а також не відповідає деяким значенням aабо bяк !або (.
⁴ в bash 3.2 і вище і за умови сумісності з bash 3.1 не включено (як у BASH_COMPAT=3.1)
⁵ хоча угруповання (тут з {...;}командою групою замість (...)якої буде працювати непотрібну подоболочкі) не є необхідним , як ||і &&оболонками операторів (на відміну від ||і && [[...]]операторів або -o/ -a [операторів) має однаковий пріоритет. Так [ a = a ] || [ a = b ] && [ a = b ]було б рівнозначно.
[[з ним код добре і зрозуміло, але пам'ятаєте той день , коли ви будете порт ваших scriptworks по системі з оболонкою по замовчуванням , який не єbashабоksh, тощо[- більш бридкий, громіздкий, але працює якAK-47у будь-якій ситуації.