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