Что Нового Появилось В Bash 4.0

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
черновики:что_нового_появилось_в_bash_4.0 [08.05.2017 18:16]
zimo
черновики:что_нового_появилось_в_bash_4.0 [20.05.2019 15:18] (текущий)
Строка 1: Строка 1:
-Изучаем новое в bash 4+ и вспоминаем старое.+ 
 +== Усовершенсвование конструкции == 
 + 
 +=== Усовершенсвование конструкции === 
 + 
 +==== Усовершенсвование конструкции ==== 
 + 
 +===== Усовершенсвование конструкции ===== 
 + 
 +====== Усовершенсвование конструкции ====== 
 +  
 + 
 +**Изучаем новое в bash 4+ и вспоминаем старое.**
  
 - Усовершенсвование конструкции `case` пр помощи ;;& и ;&. - Усовершенсвование конструкции `case` пр помощи ;;& и ;&.
  
-";&"​ - запустить действие приписанное к следующему шаблону\\ +";&"​ - запустить действие приписанное к следующему шаблону 
-";;&"​ - продолжить проверку следующих шаблонов+";;&"​ - продолжить проверку следующих шаблонов ​
  
-```\\ test_char ()\\ {\\ case "​$1"​ in\\ [[:print:]] ) echo "$1 является печатным символом с пробелом";;&​\\ # ;;& продолжит проверку следующих шаблонов.\\ [[:alnum:]] ) echo "$1 является буквой и цифрой";;&​\\ [[:alpha:]] ) echo "$1 является алфавитным символом.";;&​\\ [[:lower:]] ) echo "$1 является строчным алфавитным символом.";;&​\\ [[:digit:]] ) echo "$1 является десятичной цифрой";& ​\\ # ;& запустит действие приписанное к следующему шаблону ​\\ %%%@@@@@ ) echo "​********************************";;​\\ esac\\ }\\ ```+<code bash> 
 +test_char () 
 +{ 
 +  ​case "​$1"​ in 
 +    ​[[:print:]] )  echo "$1 является печатным символом с пробелом";;&​ 
 +    ​# ;;& продолжит проверку следующих шаблонов. 
 +    ​[[:alnum:]] )  echo "$1 является буквой и цифрой";;& ​ 
 +    ​[[:alpha:]] )  echo "$1 является алфавитным символом.";;& ​ 
 +    ​[[:lower:]] )  echo "$1 является строчным алфавитным символом.";;&​ 
 +    ​[[:digit:]] )  echo "$1 является десятичной цифрой";& ​  
 +    ​# ;& запустит действие приписанное к следующему шаблону ​       
 +    ​%%%@@@@@ ​    echo "​********************************";;​ 
 +  ​esac 
 +} 
 +</​code>​
  
 Передадим функции в качестве аргумента 8, получим Передадим функции в качестве аргумента 8, получим
  
-```\\ 8 является печатным символом с пробелом\\ 8 сожержит буквы и цифры\\ 8 является десятичной цифрой\\ ********************************\\ ```+<code bash> 
 +8 является печатным символом с пробелом 
 +8 сожержит буквы и цифры 
 +8 является десятичной цифрой 
 +******************************** 
 +</​code>​ 
  
 Передадим функции в качестве аргумента "​n",​ получим Передадим функции в качестве аргумента "​n",​ получим
  
-```\\ n является печатным символом с пробелом\\ n сожержит буквы и цифры\\ n является алфавитными символом.\\ n является строчным алфавитным символом.\\ ```\\+ 
 +<code bash> 
 +n является печатным символом с пробелом 
 +n сожержит буквы и цифры 
 +n является алфавитными символом. 
 +n является строчным алфавитным символом. 
 +</​code>​ 
 - Для управления асинхронным выполнением команд добавлено ключевое слово "​coproc"​ - Для управления асинхронным выполнением команд добавлено ключевое слово "​coproc"​
  
 Оператор coproc позволяет создавать со-процесс,​ который связан с командной оболочкой с помощью двух каналов:​ один для отправки данных в со-процесс,​ второй для получения из со-процесса. Оператор coproc позволяет создавать со-процесс,​ который связан с командной оболочкой с помощью двух каналов:​ один для отправки данных в со-процесс,​ второй для получения из со-процесса.
  
-`coproc` запускает команду в фоне и выводит пайпы так, что снаружи с ними можно взаимодействовать. опционально сопроцессу можно дать имя `NAME`.\\ +`coproc` запускает команду в фоне и выводит пайпы так, что снаружи с ними можно взаимодействовать. опционально сопроцессу можно дать имя `NAME`. 
-Если задано `NAME`, следующая команда должная быть `compound command`. Если `NAME` не задано,​ команда может быть простой командой или тоже `compound`.+Если задано `NAME`, следующая команда должная быть `compound command`. Если `NAME` не задано,​ команда может быть простой командой или тоже `compound`. ​
  
-— ${COPROC[0]} для записи;​\\+— ${COPROC[0]} для записи;​
 — ${COPROC[1]} для чтения. — ${COPROC[1]} для чтения.
  
 Соответственно,​ процедура записи/​чтения будет выглядеть примерно так: Соответственно,​ процедура записи/​чтения будет выглядеть примерно так:
  
-```\\ $ coproc tr -u a b\\ [1] 30131\\ $ echo abrakadabra1 >&​${COPROC[1]}\\ $ echo abrakadabra2 >&​${COPROC[1]}\\ $ echo abrakadabra3 >&​${COPROC[1]}\\ $ while read -u ${COPROC[0]};​ do printf "​%s\n"​ "​$REPLY";​ done\\ bbrbkbdbbrb1\\ bbrbkbdbbrb2\\ bbrbkbdbbrb3\\ ```+ 
 +<code bash> 
 + coproc tr -u a b 
 +[1] 30131 
 +$ echo abrakadabra1 >&​${COPROC[1]} 
 +$ echo abrakadabra2 >&​${COPROC[1]} 
 +$ echo abrakadabra3 >&​${COPROC[1]} 
 +$ while read -u ${COPROC[0]};​ do printf "​%s\n"​ "​$REPLY";​ done 
 +bbrbkbdbbrb1 
 +bbrbkbdbbrb2 
 +bbrbkbdbbrb3 
 +</​code>​ 
  
 а закрытие дескрипторов:​ а закрытие дескрипторов:​
  
-```\\ $ exec {COPROC[1]}>&​-\\ $ cat <&"​${COPROC[0]}"​\\ [1]+ Done coproc COPROC tr -u a b\\ ```+<code bash> 
 + 
 +$ exec {COPROC[1]}>&​- 
 +$ cat <&"​${COPROC[0]}"​ 
 +[1]+  Done                    coproc COPROC tr -u a b 
 + 
 +</​code>​
  
 Если имя COPROC по каким-то причинам не устраивает можно указать свое: Если имя COPROC по каким-то причинам не устраивает можно указать свое:
  
-```\\ $ coproc MYNAME (tr -u a b)\\ [1] 30528\\ $ echo abrakadabra1 >&​${MYNAME[1]}\\ $ read -u ${MYNAME[0]} ; echo $REPLY\\ bbrbkbdbbrb1\\ $ exec {MYNAME[1]}>&​- ; cat <&"​${MYNAME[0]}"​\\ [1]+ Done coproc MYNAME ( tr -u a b )\\ ```+<code bash> 
 +$ coproc MYNAME (tr -u a b) 
 +[1] 30528 
 +$ echo abrakadabra1 >&​${MYNAME[1]} 
 +$ read -u ${MYNAME[0]} ; echo $REPLY 
 +bbrbkbdbbrb1 
 + exec {MYNAME[1]}>&​- ; cat <&"​${MYNAME[0]}"​ 
 +[1]+  Done                    coproc MYNAME ( tr -u a b ) 
 +</​code>​
  
 - Добавлена новая встроенная команда "​mapfile"​ (плюс добавлен синоним "​readarray"​) для заполнения массива на основе строк указанного файла. - Добавлена новая встроенная команда "​mapfile"​ (плюс добавлен синоним "​readarray"​) для заполнения массива на основе строк указанного файла.
Строка 41: Строка 106:
 Синтаксис следующий:​ Синтаксис следующий:​
  
-```\\ mapfile [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-C CALLBACK] [-c QUANTUM] [ARRAY]\\ ```+<code bash> 
 +mapfile [-n COUNT] [-O ORIGIN] [-s COUNT] [-t] [-u FD] [-C CALLBACK] [-c QUANTUM] [ARRAY] 
 +</​code>​
  
 Пример Пример
  
-```\\ mapfile Arr1 < test.txt\\ echo "​${Arr1[@]}"​\\ echo "​${Arr1[@]}"​\\ #hello\\ # world\\ ```+<code bash> 
 +mapfile Arr1 < test.txt ​ 
 +echo "​${Arr1[@]}"​ 
 +echo "​${Arr1[@]}"​ 
 +#hello 
 +# world 
 +</​code>​
  
 Только вот непоятно,​ почему добавлены пробелы,​ в исходном файле пробелов нет. Только вот непоятно,​ почему добавлены пробелы,​ в исходном файле пробелов нет.
Строка 51: Строка 124:
 `read` читает только первую строку файла в массив `read` читает только первую строку файла в массив
  
-```\\ read -a Arr2 < test.txt\\ echo "​${Arr2[@]}"​\\ # hello\\ ```+<code bash> 
 +read -a Arr2 < test.txt ​ 
 +echo "​${Arr2[@]}"​ 
 +# hello 
 +</​code>​
  
 - Изменено поведение встроенной функции read в момент истечения заданного таймаута,​ который можно задать через опцию "​-t"​. Теперь при этом возвращается код ошибки больше 128 и сохраняются частично полученные до таймаута данные. Кроме того, таймаут теперь может принимать дробные значения. Дополнительно в read добавлена новая опция "​-i",​ которая позволяет при использовании readline поместить введенный текст в буфер ответа (reply buffer) - Изменено поведение встроенной функции read в момент истечения заданного таймаута,​ который можно задать через опцию "​-t"​. Теперь при этом возвращается код ошибки больше 128 и сохраняются частично полученные до таймаута данные. Кроме того, таймаут теперь может принимать дробные значения. Дополнительно в read добавлена новая опция "​-i",​ которая позволяет при использовании readline поместить введенный текст в буфер ответа (reply buffer)
Строка 57: Строка 134:
 - В команде declare появилась поддержка преобразования регистра через указание опций -l (lowercase) и -u (uppercase) - В команде declare появилась поддержка преобразования регистра через указание опций -l (lowercase) и -u (uppercase)
  
-```\\ declare -l var1\\ var1="​MixedCaseVARIABLE"​\\ echo "​$var1"​\\ # mixedcasevariable+<code bash> 
 +declare -l var1 
 +var1="​MixedCaseVARIABLE"​ 
 +echo "​$var1"​ 
 +# mixedcasevariable 
 +</​code>​
  
-```\\ 
 Capitalize? Capitalize?
  
-```\\ declare -c var2\\ var2="​originally lowercase"​\\ echo "​$var2"​\\ #Originally lowercase\\ ```+<code bash> 
 +declare -c var2 
 +var2="​originally lowercase"​ 
 +echo "​$var2"​ 
 +#Originally lowercase 
 + 
 +</​code>​
  
 - Раскрытие скобок - Раскрытие скобок
  
-```\\ echo {40..60..2}\\ # 40 42 44 46 48 50 52 54 56 58 60+<code bash> 
 +echo {40..60..2} 
 +# 40 42 44 46 48 50 52 54 56 58 60
  
-# Декремент\\ echo {60..40..2}\\ # 60 58 56 54 52 50 48 46 44 42 40+# Декремент 
 +echo {60..40..2} 
 +# 60 58 56 54 52 50 48 46 44 42 40
  
-# Так не работает\\ echo {40..60..-2}+# Так не работает 
 +echo {40..60..-2}
  
-echo {X..d}\\ # X Y Z [ ] ^ _ ` a b c d+echo {X..d} 
 +# X Y Z [  ] ^ _ ` a b c d
  
-echo {000..10}\\ # 000 001 002 003 004 005 006 007 008 009 010\\ ```+echo {000..10} 
 +# 000 001 002 003 004 005 006 007 008 009 010
  
-- Реализована новая опция "​globstar",​ при включении которой под маску `**` подпадают все директории и файлы с использованием рекурсивного перебора+</​code>​
  
-```\\ #!/bin/bash 
  
-shopt -s globstar # Необходимо включить globstar, противном случае ** не работает.+Реализована новая ​опция "​globstar",​ при ​включении которой под маску `\*\*` подпадают все директории и файлы ​с использованием рекурсивного перебора
  
-shopt -s globstar+<code bash> 
 +#!/bin/bash
  
-for filename in **; do\\ echo "​$filename"​\\ done\\ ```+shopt -s globstar # Необходимо включить globstar, противном случае `**` не работает. 
 + 
 +for filename in **; do 
 +        ​echo "​$filename"​ 
 +done 
 +</​code>​
  
 - В переменной $BASHPID теперь сохраняется идентификатор (pid) текущего процесса - В переменной $BASHPID теперь сохраняется идентификатор (pid) текущего процесса
Строка 98: Строка 197:
 - Для дополнения передаваемого следующему процессу стандартного вывода потоком ошибок,​ вместо конструкции `2>&​1` теперь можно использовать синоним `|&` - Для дополнения передаваемого следующему процессу стандартного вывода потоком ошибок,​ вместо конструкции `2>&​1` теперь можно использовать синоним `|&`
  
-- Оболочка распознает новую команду для обрезание длинных путей PROMPT_DIRTRIM. В качестве значения указывается длина пути. После превышения заданной длины в приглашении ввода будет осуществлено обрезание длинных путей, заменяя конец на ""+- Оболочка распознает новую команду для обрезание длинных путей PROMPT_DIRTRIM. В качестве значения указывается длина пути. После превышения заданной длины в приглашении ввода будет осуществлено обрезание длинных путей, заменяя конец на "..."
  
 - "​printf -v" теперь позволяет назначить значение массиву индексов - "​printf -v" теперь позволяет назначить значение массиву индексов
Строка 106: Строка 205:
 - В функцию read добавлена поддержка опции "-N число_символов",​ позволяющей считать из входного потока только заданное число символов - В функцию read добавлена поддержка опции "-N число_символов",​ позволяющей считать из входного потока только заданное число символов
  
-```\\ num_chars=5\\ read -N $num_chars var < $0 # Читает первые 5 символов\\ echo "​$var"​\\ ```+<code bash> 
 +num_chars=5 
 +read -N $num_chars var < $0   ​# Читает первые 5 символов 
 +echo "​$var"​ 
 +</​code>​
  
 - Оператор включения файлов "​source/​."​ теперь удаляет нулевые символы из файла перед парсингом команд - Оператор включения файлов "​source/​."​ теперь удаляет нулевые символы из файла перед парсингом команд
Строка 116: Строка 219:
 - Bash теперь поддерживает \u и \U - Bash теперь поддерживает \u и \U
  
-```\\ echo -e '​\u2630'​\\ \\ ```+<code bash> 
 +echo -e '​\u2630'​ 
 + 
 +</​code>​
  
 - Добавлена новая опция оболочки "​lastpipe",​ позволяющая запустить последнюю команду из конвейера (pipeline) в контексте текущей оболочки - Добавлена новая опция оболочки "​lastpipe",​ позволяющая запустить последнюю команду из конвейера (pipeline) в контексте текущей оболочки
  
-```\\ #!/bin/bash+<code bash> 
 + 
 +#​!/​bin/​bash 
 + 
 +line='' ​                   
 + 
 +shopt -s lastpipe ​         
 +head -1 $0 | read line    # Pipe the first line of the script to read. 
 +echo "\$line = "​$line""​ 
 + 
 +</​code>​ 
 + 
 +Получим 
 + 
 +<code bash> 
 + 
 +$line = #!/bin/bash 
 + 
 +</​code>​ 
 + 
 +- Отрицательные индексы массива 
 + 
 +<code bash> 
 + 
 +array=( zero one two three four five )  
 +#         ​0 ​   1   ​2 ​   3    4    5 
 +#        -6   ​-5 ​ -4   ​-3 ​  ​-2 ​  -1 
 +echo ${array[-1]} ​  # five 
 +echo ${array[-2]} ​  # four 
 + 
 +</​code>​ 
 + 
 +- Отрицательный размер,​ указанный в блоке ${var:​offset:​length} теперь не приводит к ошибке и воспринимается как обратное смещение от конца переменной 
 + 
 + 
 +<code bash> 
 +stringZ=abcABC123ABCabc 
 + 
 +echo ${stringZ} ​                             # abcABC123ABCabc 
 +#                   ​Position within string: ​   0123456789..... 
 +echo ${stringZ:​2:​3} ​                         #   cAB 
 +#  Count 2 chars forward from string beginning, and extract 3 chars. 
 +#  ${string:​position:​length} 
 +                                             # abcABC123ABCabc 
 +#                   ​Position within string: ​   0123....6543210 
 +echo ${stringZ:​3:​-6} 
 + 
 +</​code>​ 
 + 
 +- Для команд declare/​typeset добавлена новая опция "​-g",​ при указании которой переменные имеют глобальную область видимости,​ т.е. видны даже в отдельных функциях 
 + 
 +- В команде test/[/[[ добавлена поддержка оператора "​-v",​ который возвращает "​истину"​ в случае установки указанной в качестве аргумента переменной 
 + 
 +- Добавлена переменная FUNCNEST, которая позволяет ограничить уровень вложенности выполняемых функций,​ что позволяет предотвратить ситуацию бесконечной рекурсии 
 + 
 +- Во встроенной команде printf добавлена поддержка спецификатора "​%(fmt)T",​ позволяющего указать формат вывода времени в стиле strftime 
 + 
 +**4.3** 
 + 
 +- Поддержка назначения и использования элементов массивов с отрицательными значениями индекса  
 + 
 + 
 +<code bash> 
 +a[-1]=2 
 +echo ${a[-1]} # 2 
 + 
 +</​code>​ 
 + 
 +При этом, отрицательное значение задаёт обратный отчёт с последнего элемента массива (a[-1] - последний элемент,​ a[-2] - предпоследний и т.п.).  
 + 
 +- В командах return и exit добавлена возможность указания отрицательных кодов завершения работы 
 + 
 +- При указании %(...)T в printf без явного указания аргументов формата теперь выводится текущее время.  
 + 
 + 
 +<code bash> 
 +printf '​%(%Y%m%d)T\n'​ 
 +# 20170217 
 +</​code>​ 
 + 
 +**4.4** 
 + 
 +- Во встроенной команде mapfile появилась возможность определения произвольного символа-разделителя записей (опция "​-d"​) 
  
-line=''​+<code bash> 
 +mapfile -d ""​ arr_mapfile < <(find -print0) 
 +echo "​arr_mapfile contains ${#​arr_mapfile[@]} files"​ 
 +# arr_mapfile contains 56380 files
  
-shopt -s lastpipe \\ head -1 $0 | read line # Pipe the first line of the script to read.\\ echo "​\$line = "​$line_ckgedit_QUOT__ckgedit>​\\ ``` Получим ```\\ $line = #!/bin/bash\\ ``` - Отрицательные индексы массива ```\\ array=( zero one two three four five )\\ # 0 1 2 3 4 5\\ # -6 -5 -4 -3 -2 -1\\ echo ${array[-1]} # five\\ echo ${array[-2]} # four\\ ``` - Отрицательный размер,​ указанный в блоке ${var:​offset:​length} теперь не приводит к ошибке и воспринимается как обратное смещение от конца переменной ```\\ stringZ=abcABC123ABCabc echo ${stringZ} # abcABC123ABCabc\\ # Position within string: 0123456789.....\\ echo ${stringZ:​2:​3} # cAB\\ # Count 2 chars forward from string beginning, and extract 3 chars.\\ # ${string:​position:​length}\\ # abcABC123ABCabc\\ # Position within string: 0123....6543210\\ echo ${stringZ:​3:​-6}\\ ``` - Для команд declare/​typeset добавлена новая опция "​-g",​ при указании которой переменные имеют глобальную область видимости,​ т.е. видны даже в отдельных функциях - В команде test/[/[[ добавлена поддержка оператора "​-v",​ который возвращает "​истину"​ в случае установки указанной в качестве аргумента переменной - Добавлена переменная FUNCNEST, которая позволяет ограничить уровень вложенности выполняемых функций,​ что позволяет предотвратить ситуацию бесконечной рекурсии - Во встроенной команде printf добавлена поддержка спецификатора "​%(fmt)T",​ позволяющего указать формат вывода времени в стиле strftime #### 4.3 - Поддержка назначения и использования элементов массивов с отрицательными значениями индекса ```\\ a[-1]=2\\ echo ${a[-1]} # 2\\ ``` При этом, отрицательное значение задаёт обратный отчёт с последнего элемента массива (a[-1] - последний элемент,​ a[-2] - предпоследний и т.п.). - В командах return и exit добавлена возможность указания отрицательных кодов завершения работы - При указании %(…)T в printf без явного указания аргументов формата теперь выводится текущее время. ```\\ printf '​%(%Y%m%d)T\n'​\\ # 20170217\\ ``` #### 4.4 - Во встроенной команде mapfile появилась возможность определения произвольного символа-разделителя записей (опция "​-d"​) ```\\ mapfile -d _ckgedit_QUOT__ckgeditarr_mapfile < <(find -print0)\\ echo "​arr_mapfile contains ${#​arr_mapfile[@]} files"​\\ # arr_mapfile contains 56380 files\\ ```+</code>