I. Круглые скобки ()
1. Одиночные круглые скобки ()
- Группировка командКоманды внутри круглых скобок будут выполняться последовательно в новой подоболочке, поэтому переменные внутри круглых скобок не могут использоваться остальной частью скрипта. Несколько команд внутри круглых скобок разделяются точками с запятой; в последней команде точку с запятой можно опустить, а пробелы между командами и скобками не нужны.
- Подстановка командЭквивалентно `cmd`. Когда оболочка сканирует командную строку и находит конструкцию $(cmd), она выполняет cmd один раз, получает её стандартный вывод и помещает этот вывод в исходную команду. Некоторые оболочки не поддерживают её, например tcsh.
- Используется для инициализации массивовПример: array=(a b c d)
2. Двойные круглые скобки (( ))
- Целочисленное расширение. Это расширение выполняет целочисленную арифметику и не поддерживает числа с плавающей запятой. Конструкция ((exp)) раскрывается и вычисляет значение арифметического выражения. Если результат выражения равен 0, она возвращает статус выхода 1, или "false"; если выражение имеет ненулевое значение, она возвращает статус выхода 0, или "true". Если используется как логическая проверка, выражение exp равно 1, когда истинно, и 0, когда ложно.
- Пока операторы и выражения внутри круглых скобок подчиняются правилам операций языка C, их можно использовать в $((exp)), даже тернарный оператор. При выполнении операций в разных системах счисления (например, двоичной, восьмеричной, шестнадцатеричной) выходные результаты автоматически преобразуются в десятичную систему счисления. Например: echo $((16#5f)) даёт 95 (из шестнадцатеричной в десятичную).
- Простое использование (( )) также может переопределять значения переменных, например: a=5; ((a++)) может переопределить $a на 6.
- Обычно используется для арифметических сравнений. Переменным внутри двойных круглых скобок не нужен префикс $. Поддерживается несколько выражений внутри, разделённых запятыми. При условии, что выражения внутри скобок соответствуют правилам языка C. Например, можно напрямую использовать for((i=0;i<5;i++)); если не использовать двойные круглые скобки, это было бы for i in `seq 0 4` или for i in {0..4}. Другой пример: можно напрямую использовать if (($i<5)); если не использовать двойные круглые скобки, это было бы if [ $i -lt 5 ].
II. Скобки, квадратные скобки []
1. Одинарные квадратные скобки []
- [ — внутренняя команда bash, и [ и test эквивалентны. Если мы не указываем абсолютный путь, обычно используемая нами команда — это встроенная команда bash. В структуре if/test левая квадратная скобка — это токен команды, который вызывает test, а правая квадратная скобка закрывает условную проверку. Эта команда рассматривает свои аргументы как выражение сравнения или как проверку файла и возвращает код завершения на основе результата сравнения. Правая квадратная скобка не является строго обязательной в структуре if/test, но более новые версии Bash требуют её.
- В test и [] единственными доступными операторами сравнения являются == и !=; оба используются для сравнения строк и не могут использоваться для сравнения целых чисел. Для сравнения целых чисел допускаются только формы вроде -eq, -gt. Ни сравнение строк, ни сравнение целых чисел не поддерживает знаки больше или меньше. Если вы действительно хотите использовать их для сравнения строк, можно применить экранированную форму. Например, сравнение "ab" и "bc": [ ab \< bc ] истинно, то есть возвращает статус 0. Логическое И и логическое ИЛИ в [ ] обозначаются -a и -o.
- Диапазон символов. Используется как часть регулярного выражения для описания соответствующего диапазона символов. Регулярные выражения нельзя использовать внутри квадратных скобок, когда они применяются для целей проверки.
- В контексте структуры массива квадратные скобки используются для ссылки на индекс каждого элемента массива.
2. Двойные квадратные скобки [[ ]]
- [[ — это ключевое слово в языке программирования bash. Это не команда; конструкция [[ ]] более универсальна, чем конструкция [ ]. Между [[ и ]] не происходит раскрытия имён файлов или разделения слов, но происходят раскрытие параметров и подстановка команд.
- Оно поддерживает сопоставление строк с шаблоном; с оператором =~ он даже поддерживает регулярные выражения shell. При сравнении строк правую часть можно рассматривать как шаблон, а не просто как строку, например [[ hello == hell? ]] истинно. В [[ ]] кавычки не нужны при сопоставлении строк или подстановочных знаков.
- Использование конструкции условной проверки [[ ... ]] вместо [ ... ] может предотвратить множество логических ошибок в сценариях. Например, операторы &&, ||, < и > корректно работают в конструкции [[ ]], но если они появляются в [ ], будет выдана ошибка. Например, можно напрямую использовать if [[ $a != 1 && $a != 2 ]]; если не использовать двойные скобки, это было бы if [ $a -ne 1] && [ $a != 2 ] или if [ $a -ne 1 -a $a != 2 ].
- Bash рассматривает выражение внутри двойных квадратных скобок как единый элемент и возвращает код состояния выхода.
if ($i<5)
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4);do echo $i;done
for i in `seq 0 4`;do echo $i;done
for ((i=0;i<5;i++));do echo $i;done
for i in {0..4};do echo $i;done
III. Фигурные скобки {}
1. Обычное использование
(1) Развёртывание фигурных скобок. (Глоббинг) развёртывает имена файлов внутри фигурных скобок. Внутри фигурных скобок пробельные символы не допускаются, если они не заключены в кавычки или не экранированы. Первый тип: развёртывает список файлов, разделённых запятыми, внутри фигурных скобок, например, touch {a,b}.txt даёт в результате a.txt b.txt. Второй тип: развёртывает последовательный список файлов, разделённых двумя точками (..), внутри фигурных скобок, например, touch {a..d}.txt даёт в результате a.txt b.txt c.txt d.txt
# ls {ex1,ex2}.sh
ex1.sh ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
(2) Блок кода, также известный как внутренняя группа. Эта конструкция фактически создаёт анонимную функцию. В отличие от команд в круглых скобках, команды внутри фигурных скобок не выполняются в новой подоболочке, поэтому остальная часть сценария по-прежнему может использовать переменные внутри фигурных скобок. Команды внутри фигурных скобок разделяются точками с запятой, и последняя также должна иметь точку с запятой. Между первой командой и левой фигурной скобкой в {} должен быть пробел.
2. Несколько специальных конструкций подстановки
${var:-string}
${var:+string}
${var:=string}
${var:?string}
1. ${var:-string} и ${var:=string}: Если переменная var пуста, то на командной строке для замены ${var:-string} используется string; в противном случае, если var не пуста, для замены ${var:-string} используется значение var. Правило подстановки для ${var:=string} такое же, как для ${var:-string}, за исключением того, что когда var пуста, ${var:=string} заменяет её на string и также присваивает string переменной var. Очень распространённое использование ${var:=string} — проверить, было ли переменной присвоено значение, и если нет, присвоить ей значение по умолчанию.
2. Правило подстановки для ${var:+string} противоположно вышеописанному. То есть оно заменяется на string только когда var не пуста; если var пуста, оно не заменяется, или, что эквивалентно, заменяется значением var, которое пусто. (Поскольку в этот момент var пуста, эти два утверждения эквивалентны.)
3. Правило подстановки для {var:?string}: если переменная var не пуста, то используйте значение var для замены ${var:?string}; если var пуста, выведите string в стандартный поток ошибок и завершите скрипт. Мы можем использовать эту возможность, чтобы проверить, была ли задана переменная.
Дополнительное раскрытиеВ приведённых пяти конструкциях подстановки string не обязательно является константой; это может быть значение другой переменной или вывод команды.
3. Четыре конструкции подстановки с сопоставлением по шаблону
Мнемоническое правило для сопоставления с шаблоном:
# removes the left side (on the keyboard, # is to the left of $) % removes the right side (on the keyboard, % is to the right of $)
Одиночный символ в # и % — это самое короткое совпадение, а два одинаковых символа — самое длинное совпадение.
${var%pattern}
${var%%pattern
${var#pattern}
${var##pattern}
- Первый шаблон: ${variable%pattern}. В этом шаблоне оболочка проверяет, заканчивается ли variable заданным шаблоном. Если да, она удаляет из содержимого variable в командной строке самый короткий совпадающий шаблон справа.
- Второй шаблон: ${variable%%pattern}. В этом шаблоне оболочка проверяет, заканчивается ли variable заданным шаблоном. Если да, она удаляет из содержимого variable в командной строке самый длинный совпадающий шаблон справа.
- Третий шаблон: ${variable#pattern}. В этом шаблоне оболочка проверяет, начинается ли variable с заданного шаблона. Если да, она удаляет из содержимого variable в командной строке самый короткий совпадающий шаблон слева.
- Четвёртый шаблон: ${variable##pattern}. В этом шаблоне оболочка проверяет, заканчивается ли variable заданным шаблоном. Если да, она удаляет из содержимого variable в командной строке самый длинный совпадающий шаблон справа.
- Во всех этих четырёх режимах значение variable никогда не изменяется. Среди них только при использовании в шаблоне символа сопоставления * различаются % и %%, # и ##. Шаблон в конструкции поддерживает подстановочные знаки: * обозначает ноль или более произвольных символов, ? соответствует ровно одному произвольному символу, [...] соответствует символам внутри скобок, а [!...] не соответствует символам внутри скобок.
# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}
# echo ${var##*s}
e
# echo ${var##test}
case
4. Извлечение и замена строк
${var:num}
${var:num1:num2}
${var/pattern/pattern}
${var//pattern/pattern}
- Первый режим: ${var:num}. В этом режиме shell извлекает все символы с num-го символа до конца var. Если num положительное, извлечение начинается с позиции 0 слева; если num отрицательное, подстрока извлекается начиная справа, но после двоеточия нужно добавить пробел, либо использовать число, либо заключить весь num в круглые скобки, например ${var: -2}, ${var:1-3} или ${var:(-2)}.
- Второй режим: ${var:num1:num2}, где num1 — позиция, а num2 — длина. Это означает извлечение подстроки длиной $num2 начиная с позиции $num1 в строке $var. Отрицательные числа не допускаются.
- Третий режим: ${var/pattern/pattern} означает замену первого вхождения pattern, совпавшего в строке var, на другой pattern.
- Четвертый режим: ${var//pattern/pattern} означает замену всех вхождений pattern, совпавших в строке var, на другой pattern.
[root@centos ~]# var=/home/centos
[root@centos ~]# echo $var
/home/centos
[root@centos ~]# echo ${var:5}
/centos
[root@centos ~]# echo ${var: -6}
centos
[root@centos ~]# echo ${var:(-6)}
centos
[root@centos ~]# echo ${var:1:4}
home
[root@centos ~]# echo ${var/o/h}
/hhme/centos
[root@centos ~]# echo ${var//o/h}
/hhme/cenths
IV. Скобки после символа $
- (1) ${a} — это значение переменной a. Фигурные скобки можно опустить, когда это не вызывает неоднозначности.
- (2) $(cmd) — это подстановка команд, которая имеет тот же эффект, что и `cmd`. Результатом является вывод shell-команды cmd. Однако некоторые версии Shell не поддерживают подстановку команд $(), например tcsh.
- (3) $((expression)) имеет тот же эффект, что и `expr expression`. Он вычисляет числовое значение математического выражения exp. Если exp соответствует правилам операций языка C, можно вычислять даже тернарные операторы и логические выражения.
V. Использование
-
1. Выполнение нескольких команд
- (1) Одиночные круглые скобки, (cmd1;cmd2;cmd3): запускают новую подоболочку для последовательного выполнения команд cmd1, cmd2, cmd3, разделенных точкой с запятой. Последняя команда не нуждается в завершающей точке с запятой.
- (2) Одинарные фигурные скобки, { cmd1;cmd2;cmd3; }: выполняют команды cmd1, cmd2, cmd3 последовательно в текущей оболочке, разделяя их точками с запятой. После последней команды должна стоять точка с запятой, и между первой командой и открывающей фигурной скобкой должен быть пробел.
Пара{}и()В этом отношении оператор перенаправления внутри круглых скобок влияет только на эту отдельную команду, тогда как оператор перенаправления вне круглых скобок влияет на все команды внутри круглых скобок.
Первоисточник: http://blog.csdn.net/taiyang1987912/article/details/39551385