echo - n ${VarNull-'NotSet'}' ' # NotSet
echo ${VarNull} # только перевод строки
echo - n ${VarNull:-'NotSet'}' ' # NotSet
echo ${VarNull} # только перевод строки
echo '- "пустая" переменная -'
echo - n ${VarEmpty-'Empty'}' ' # только пробел
echo ${VarEmpty} # только перевод строки
echo - n ${VarEmpty:-'Empty'}' ' # Empty
echo ${VarEmpty} # только перевод строки
echo '- непустая переменная -'
echo ${VarSomething-'Content'} # Literal
echo ${VarSomething:-'Content'} # Literal
echo '- Разреженный массив -'
echo ${ArrayVar[@]-'not set'}
# ASCII-Art time
# State Y==yes, N==no
# - :-
# Unset Y Y ${# ... } == 0
# Empty N Y ${# ... } == 0
# Contents N N ${# ... } > 0
# Либо первая, либо вторая часть операции подстановки параметра по-умолчанию
#+ может быть командой или вызовом функции.
echo
echo '- - Тест 1, не определенная переменная - -'
declare - i t
_decT() {
t=$t-1
}
# Для не определенной переменной: t == -1
t=${#VarNull} # t == 0
${VarNull - _decT } # Вызов функции, теперь t == -1.
echo $t
# "Пустая" переменная: t == 0
t=${#VarEmpty} # t == 0
${VarEmpty - _decT } # Функция _decT НЕ вызывается.
echo $t
# Непустая переменная: t == число непустых символов
VarSomething='_simple' # Записать имя функции в переменную.
t=${#VarSomething} # ненулевая длина
${VarSomething - _decT } # Вызывается функция _simple.
echo $t # Обратите внимание на вывод.
# Упражнение: Разберитесь в этом примере.
unset t
unset _decT
VarSomething=Literal
echo
echo '- - Тест (с изменением содержимого переменной) - -'
echo '- Присвоить, если переменная не определена -'
echo - n ${VarNull='NotSet'}' ' # NotSet NotSet
echo ${VarNull}
unset VarNull
echo '- Присвоить, если переменная не определена -'
echo - n ${VarNull:='NotSet'}' ' # NotSet NotSet
echo ${VarNull}
unset VarNull
echo '- Не присваивать, если переменная пуста -'
echo - n ${VarEmpty='Empty'}' ' # только пробел
echo ${VarEmpty}
VarEmpty=''
echo '- Присвоить, если переменная пуста -'
echo - n ${VarEmpty:='Empty'}' ' # Empty Empty
echo ${VarEmpty}
VarEmpty=''
echo '- Не изменять, если переменная не пуста -'
echo ${VarSomething='Content'} # Literal
echo ${VarSomething:='Content'} # Literal
# "Разреженные" Bash-Массивы
###
# Bash-Массивы не содержат пустых элементов, и индексация их,
#+ если не оговорено иное, начинается с нуля.
###
# Инициализируем массив ArraySparse как раз тем способом,
#+ когда "оговорено иное". Ниже приведен один из вариантов:
###
echo
declare - a ArraySparse
ArraySparse=( [1]=one [2]='' [4]='four' )
# [0]=нет элемента, [2]=пустой элемент, [3]=нет элемента
echo '- - Разреженный массив - -'
# В двойных кавычках, значение IFS -- по-умолчанию, Все-Элементы-Для
IFS=$'\x20'$'\x09'$'\x0A'
printf %q "${ArraySparse[*]}"
echo
# Обратите внимание на отсутствие различий в том, как выводятся отсутствующий
#+ и пустой элементы массива.
# Оба выводятся как экранированные пробелы.
###
# Не упустите из виду и то, что все неопределенные элементы массива,
#+ предшествующие первому инициализированному элементу, не выводятся
###
# Замечание о таком "поведении" Bash, версий 2.04, 2.05a и 2.05b,
#+ было передано разработчикам has been reported
#+ и возможно будет изменено в последующих версиях Bash.
# Чтобы вывести содержимое такого разреженного массива без изменений
#+ требуется некоторое количество усилий.
# Вот один из возможных вариантов вывода такого массива:
###
# local l=${#ArraySparse[@]} # Количество инициализированных элементов
# local f=0 # Количество найденных индексов
# local i=0 # текущий индекс
( # Анонимная функция
for (( l=${#ArraySparse[@]}, f = 0, i = 0 ; f < l ; i++ ))
do
# 'if defined then...'
${ArraySparse[$i]+ eval echo '\ ['$i']='${ArraySparse[$i]} ; (( f++ )) }
done
)
# Важно:
# Команда "read - a array_name" начинает заполнять массив
#+ array_name с нулевого элемента.
# ArraySparse -- не содержит нулевого элемента.
###
# Для выполнения операций над разреженными массивами,
#+ такими как чтение/запись массива из/в файла
#+ программист должен сам создать программный код, который
#+ будет удовлетворять его потребности.
###
# Упражнение: разберитесь в следующем примере самостоятельно.
unset ArraySparse
echo
echo '- - Замена по условию (замена не производится)- -'
echo '- Не изменять если переменная не определена -'
echo - n ${VarNull+'NotSet'}' '
echo ${VarNull}
unset VarNull
echo '- Не изменять если переменная не определена -'
echo - n ${VarNull:+'NotSet'}' '
echo ${VarNull}
unset VarNull
echo '- Изменить если переменная пуста -'
echo - n ${VarEmpty+'Empty'}' ' # Empty
echo ${VarEmpty}
VarEmpty=''
echo '- Не изменять если переменная пуста -'
echo - n ${VarEmpty:+'Empty'}' ' # Только пробел
echo ${VarEmpty}
VarEmpty=''
echo '- Изменить, если переменная не пуста -'
echo - n ${VarSomething+'Content'}' ' # Content Literal
echo ${VarSomething}
# Вызов функции
echo - n ${VarSomething:+ $(_simple) }' ' # SimpleFunc Literal
echo ${VarSomething}
echo
echo '- - Разреженный массив - -'
echo ${ArrayVar[@]+'Empty'} # An array of 'Empty'(ies)
echo
echo '- - Тест 2, неопределенные переменные - -'
declare - i t
_incT() {
t=$t+1
}
# Обратите внимание:
# Тот же самый тест, что и в случае с разреженными массивами
# Неопределенная переменная: t == -1
t=${#VarNull}-1 # t == -1
${VarNull+ _incT } # Функция не вызывается.
echo $t' Переменная не определена'
# Пустая переменная: t == 0
t=${#VarEmpty}-1 # t == -1
${VarEmpty+ _incT } # Вызов функции.
echo $t' Переменная пуста'
# Переменная не пуста: t == (количество непустых символов)
t=${#VarSomething}-1 # количество_непустых_символов минус один
${VarSomething+ _incT } # Вызов функции.
echo $t' Переменная не пуста'
# Операции над элементами массива
#
echo
echo '- - Выборка элементов - -'
# Строки, массивы и позиционные параметры
# Чтобы увидеть работу сценария с позиционными параметрами,
#+ вызовите его с несколькими аргументами
echo '- Все -'
echo ${VarSomething:0} # все не пустые символы
echo ${ArrayVar[@]:0} # все не пустые элементы
echo ${@:0} # все не пустые параметры;
# параметр [0] игнорируется
echo
echo '- Все после -'
echo ${VarSomething:1} # все не пустые символы, стоящие после [0]
echo ${ArrayVar[@]:1} # все не пустые элементы, стоящие после [0]
echo ${@:2} # все не пустые параметры, стоящие после [1]
echo
echo '- Диапазон символов -'
echo ${VarSomething:4:3} # ral
# Три символа, следующие
# за символом [3]
echo '- Разреженный массив -'
echo ${ArrayVar[@]:1:2} # four - Единственный непустой элемент.
# Чтобы убедиться в том, что Bash в данной ситуации рассматривает только
#+ непустые элементы
# printf %q "${ArrayVar[@]:0:3}" # Попробуйте раскомментарить эту строку
# Версии Bash 2.04, 2.05a и 2.05b,
#+ работают с разреженными массивами не так как ожидается.
#
# Chet Ramey обещал исправить это в последующих версиях Bash.
echo '- Неразреженный массив -'
echo ${@:2:2} # За параметром [1] следуют еще два параметра
# Простые примеры со строками и массивами строк:
stringZ=abcABC123ABCabc
arrayZ=( abcabc ABCABC 123123 ABCABC abcabc )
sparseZ=( [1]='abcabc' [3]='ABCABC' [4]='' [5]='123123' )
echo
echo ' - - Простая строка - -'$stringZ'- - '
echo ' - - Простой массив - -'${arrayZ[@]}'- - '
echo ' - - Разреженный массив - -'${sparseZ[@]}'- - '
echo ' - [0]==нет элемента, [2]==нет элемента, [4]==пустой элемент - '
echo ' - [1]=abcabc [3]=ABCABC [5]=123123 - '
echo ' - количество инициализированных элементов: '${#sparseZ[@]}
echo
echo '- - Префиксы - -'
echo '- - Шаблон должен совпадать с первым символом строки. - -'
echo '- - Шаблон может быть строкой или результатом работы функции. - -'
echo
# Функция, результатом работы которой является обычная строка
_abc() {
echo - n 'abc'
}
echo '- Кратчайший префикс -'
echo ${stringZ#123} # Без изменения -- не префикс.
echo ${stringZ#$(_abc)} # ABC123ABCabc
echo ${arrayZ[@]#abc} # Применяется к каждому элементу массива.
# Chet Ramey обещал исправить в последующих версиях Bash.
# echo ${sparseZ[@]#abc} # В версии 2.05b -- core dumps.
# - Это было бы здорово - First-Subscript-Of (Первый-Индекс-Массива)
# echo ${#sparseZ[@]#*} # line 805: ${#sparseZ[@]#*}: bad substitution.
echo
echo '- Наибольший префикс -'
echo ${stringZ##1*3} # Без изменения -- не префикс.
echo ${stringZ##a*C} # abc
echo ${arrayZ[@]##a*c} # ABCABC 123123 ABCABC
# Chet Ramey обещал исправить в последующих версиях Bash.
# echo ${sparseZ[@]##a*c} # В версии 2.05b -- core dumps.
echo
echo '- - Суффиксы - -'
echo '- - Шаблон должен совпадать с последним символом строки. - -'
echo '- - Шаблон может быть строкой или результатом работы функции. - -'
echo
echo '- Кратчайший суффикс -'
echo ${stringZ%1*3} # Без изменения -- не суффикс.
echo ${stringZ%$(_abc)} # abcABC123ABC
echo ${arrayZ[@]%abc} # Применяется к каждому элементу массива.
# Chet Ramey обещал исправить в последующих версиях Bash.
# echo ${sparseZ[@]%abc} # В версии 2.05b -- core dumps.
# - Это было бы здорово - Last-Subscript-Of (Последний-Индекс-Массива)
# echo ${#sparseZ[@]%*} # line 830: ${#sparseZ[@]%*}: bad substitution
echo
echo '- Наибольший суффикс -'
echo ${stringZ%%1*3} # Без изменения -- не суффикс.
echo ${stringZ%%b*c} # a
echo ${arrayZ[@]%%b*c} # a ABCABC 123123 ABCABC a
# Chet Ramey обещал исправить в последующих версиях Bash.
# echo ${sparseZ[@]%%b*c} # В версии 2.05b -- core dumps.
echo
echo '- - Замена подстроки - -'
echo '- - Подстрока может находиться в любом месте в строке. - -'
echo '- - Первый описатель задает шаблон поиска - -'
echo '- - Шаблон может быть строкой или результатом работы функции. - -'
echo '- - Второй описатель может быть строкой или результатом работы функции. - -'
echo '- - Второй описатель может быть опущен. В результате получится:'
echo ' Заменить-Ничем (Удалить) - -'
echo
# Функция, результатом работы которой является обычная строка
_123() {
echo - n '123'
}
echo '- Замена первого вхождения -'
echo ${stringZ/$(_123)/999} # Подстрока 123 заменена на 999).
echo ${stringZ/ABC/xyz} # xyzABC123ABCabc
echo ${arrayZ[@]/ABC/xyz} # Применяется ко всем элементам массива.
echo ${sparseZ[@]/ABC/xyz} # Работает так как и ожидается.
echo
echo '- Удаление первого вхождения -'
echo ${stringZ/$(_123)/}
echo ${stringZ/ABC/}
echo ${arrayZ[@]/ABC/}
echo ${sparseZ[@]/ABC/}
# Замещающий элемент необязательно должен быть строкой,
#+ допускается употреблять результат функции.
# Это применимо ко всем формам замены.
echo
echo '- Замена первого вхождения результатом работы функции -'
echo ${stringZ/$(_123)/$(_simple)} # Работает так как и ожидается.
echo ${arrayZ[@]/ca/$(_simple)} # Применяется ко всем элементам массива.
echo ${sparseZ[@]/ca/$(_simple)} # Работает так как и ожидается.
echo
echo '- Замена всех вхождений -'
echo ${stringZ//[b2]/X} # все символы b и 2 заменяются символом X
echo ${stringZ//abc/xyz} # xyzABC123ABCxyz
echo ${arrayZ[@]//abc/xyz} # Применяется ко всем элементам массива.
echo ${sparseZ[@]//abc/xyz} # Работает так как и ожидается.
echo
echo '- Удаление всех вхождений -'
echo ${stringZ//[b2]/}
echo ${stringZ//abc/}
echo ${arrayZ[@]//abc/}
echo ${sparseZ[@]//abc/}
echo
echo '- - Замена префикса - -'
echo '- - Шаблон должен совпадать с первым символом строки. - -'
echo
echo '- - Замена префикса - -'
echo ${stringZ/#[b2]/X} # Без изменения -- не префикс.
echo ${stringZ/#$(_abc)/XYZ} # XYZABC123ABCabc
echo ${arrayZ[@]/#abc/XYZ} # Применяется ко всем элементам массива.
echo ${sparseZ[@]/#abc/XYZ} # Работает так как и ожидается.
echo
echo '- Удаление префикса -'
echo ${stringZ/#[b2]/}
echo ${stringZ/#$(_abc)/}
echo ${arrayZ[@]/#abc/}
echo ${sparseZ[@]/#abc/}
echo
echo '- - Замена суффикса - -'
echo '- - Шаблон должен совпадать с последним символом строки. - -'
echo
echo '- - Замена суффикса - -'
echo ${stringZ/%[b2]/X} # Без изменения -- не суффикс.
echo ${stringZ/%$(_abc)/XYZ} # abcABC123ABCXYZ
echo ${arrayZ[@]/%abc/XYZ} # Применяется ко всем элементам массива.
echo ${sparseZ[@]/%abc/XYZ} # Работает так как и ожидается.
echo
echo '- Удаление суффикса -'
echo ${stringZ/%[b2]/}
echo ${stringZ/%$(_abc)/}
echo ${arrayZ[@]/%abc/}
echo ${sparseZ[@]/%abc/}
echo
echo '- - Специальный случай -- пустой шаблон поиска - -'
echo
echo '- Префикс -'
# пустой шаблон означает простую вставку в начало строки
echo ${stringZ/#/NEW} # NEWabcABC123ABCabc
echo ${arrayZ[@]/#/NEW} # Применяется ко всем элементам массива.
echo ${sparseZ[@]/#/NEW} # И к неинициализированным элементам тоже
echo
echo '- Суффикс -'
# пустой шаблон означает простое добавление в конец строки
echo ${stringZ/%/NEW} # abcABC123ABCabcNEW
echo ${arrayZ[@]/%/NEW} # Применяется ко всем элементам массива.
echo ${sparseZ[@]/%/NEW} # И к неинициализированным элементам тоже
echo
echo '- - Специальный случай оператора For-Each - -'
echo 'This is a nice-to-have dream '
echo
_GenFunc() {
echo - n ${0} # Только как иллюстрация.
# Фактически здесь может стоять любое другое выражение.
}
# Все вхождения, совпадающие с шаблоном "*"
# В настоящее время, шаблон //*/ не совпадает с пустыми
#+ и неинициализированными элементами.
# В то время как шаблоны /#/ и /%/ совпадают с пустыми и не совпадают
#+ с неинициализированными элементами.
echo ${sparseZ[@]//*/$(_GenFunc)}
exit 0
Приложение B. Справочная информация
В нижеследующем справочнике представлена информация, касающаяся отдельных моментов написания сценариев на языке командной оболочки Bash.
Таблица B-1. Переменные специального назначения
Переменная | Описание |
$0 | Имя файла сценария |
$1 | Позиционный параметр #1 (аргумент сценария или функции) |
$2 - $9 | Позиционные параметры #2 - #9 |
${10} | Позиционный параметр #10 |
$# | Количество позиционных параметров |
"$*" | Все позиционные параметры (как одно слово) * |
"$@" | Все позиционные параметры (в виде отдельных строк) |
${#*} | Количество позиционных параметров, переданых из командной строки |
${#@} | Количество позиционных параметров, переданых из командной строки |
$? | Возвращаемое значение |
$$ | Идентификатор процесса -- Process ID (PID) сценария |
$- | Флаги, переданные сценарию (командой set) |
$_ | Последний аргумент предыдущей команды |
$! | Идентификатор последнего фонового процесса (PID) |
* Необходимо заключать в кавычки, в противном случае будет работать как "$@".
Таблица B-2. Операции проверки: Двухместные операции
Оператор | Значение | ----- | Оператор | Значение |
Арифметическое сравнение | Сравнение строк | |||
-eq | Равно | = | Равно | |
== | Равно | |||
-ne | Не равно | != | Не равно | |
-lt | Меньше | \< | Меньше (в кодах ASCII) * | |
-le | Меньше или равно | |||
-gt | Больше | \> | Больше (в кодах ASCII) * | |
-ge | Больше или равно | |||
-z | Пустая строка | |||
-n | Не пустая строка | |||
Арифметическое сравнение | В двойных круглых скобках | |||
> | Больше | |||
>= | Больше или равно | |||
< | Меньше | |||
<= | Меньше или равно |
* При использовании двойных квадратных скобок [[ ... ]] , необходимо использовать экранирующий символ \ .
Таблица B-3. Операции проверки: Файлы
Оператор | Что проверяется | ----- | Оператор | Что проверяется |
-e | Файл существует | -s | Файл не нулевой длины | |
-f | Обычный файл | |||
-d | Файл является каталогом | -r | Файл доступен для чтения | |
-h | Файл является символической ссылкой | -w | Файл доступен для записи | |
-L | Файл является символической ссылкой | -x | Файл доступен для исполнения | |
-b | Файл блочного устройства | |||
-c | Файл символного устройства | -g | Установлен флаг sgid | |
-p | Файл является каналом (pipe) | -u | Установлен флаг suid | |
-S | Файл является сокетом (socket) | -k | Установлен бит "sticky" | |
-t | Файл связан с терминальным устройством | |||
-N | Файл был модифицирован с момента последнего чтения | F1 - nt F2 | Файл F1 более новый, чем F2 * | |
-O | Вы являетесь владельцем файла | F1 - ot F2 | Файл F1 более старый, чем F2 * | |
-G | Вы принадлежите к той же группе, что и файл | F1 - ef F2 | Файлы F1 и F2 являются жесткими ссылками на один и тот же файл * | |
! | "NOT" (логическое отрицание (инверсия) результатов всех вышеприведенных проверок) |
* Двухместный оператор (требует наличия двух операндов).
Таблица B-4. Подстановка параметров и экспансия
Выражение | Описание |
${var} | Значение переменной var, то же, что и $var |
${var-DEFAULT} | Если переменная var не инициализирована, то результатом вычисления выражения является $DEFAULT * |
${var:-DEFAULT} | Если переменная var не инициализирована или пуста, то результатом вычисления выражения является $DEFAULT * |
${var=DEFAULT} | Если переменная var не инициализирована, то результатом вычисления выражения является $DEFAULT * |
${var:=DEFAULT} | Если переменная var не инициализирована, то результатом вычисления выражения является $DEFAULT * |
${var+OTHER} | Если переменная var инициализирована, то результатом вычисления выражения является $OTHER, иначе -- пустая строка |
${var:+OTHER} | Если переменная var инициализированаset, то результатом вычисления выражения является $OTHER, иначе -- пустая строка |
${var? ERR_MSG} | Если переменная var не инициализирована, то выводится $ERR_MSG * |
${var:?ERR_MSG} | Если переменная var не инициализирована, то выводится $ERR_MSG * |
${!varprefix*} | Соответствует всем ранее объявленным переменным, чьи имена начинаются с varprefix |
${!varprefix@} | Соответствует всем ранее объявленным переменным, чьи имена начинаются с varprefix |
* Само собой разумеется, если переменная var инициализирована, то результатом выражения будет $var.
Таблица B-5. Операции со строками
Выражение | Описание |
${#string} | Длина строки $string |
${string:position} | Извлечение подстроки из строки $string, начиная с позиции $position |
${string:position:length} | Извлечение $length символов из строки $string, начиная с позиции $position |
${string#substring} | Поиск кратчайшего совпадения по шаблону $substring, в строке $string, поиск ведется с начала строки |
${string##substring} | Поиск самого длинного совпадения по шаблону $substring, в строке $string, поиск ведется с начала строки |
${string%substring} | Поиск кратчайшего совпадения по шаблону $substring, в строке $string, поиск ведется с конца строки |
${string%%substring} | Поиск самого длинного совпадения по шаблону $substring, в строке $string, поиск ведется с конца строки |
${string/substring/replacement} | Замена первой, найденой по шаблону $substring, подстроки на подстроку $replacement |
${string//substring/replacement} | Замена всех, найденых по шаблону $substring, подстрок на подстроку $replacement |
${string/#substring/replacement} | Если в строке $string найдено соответствие шаблону $substring и найденая подстрока начинает строку $string, то она заменяется подстрокой $replacement |
Если в строке $string найдено соответствие шаблону $substring и найденая подстрока заканчивает строку $string, то она заменяется подстрокой $replacement | |
expr match "$string" '$substring' | Количество совпадений с шаблоном $substring* в строке $string, поиск начинается с начала строки |
expr "$string" : '$substring' | Количество совпадений с шаблоном $substring* в строке $string, поиск начинается с начала строки |
expr index "$string" $substring | Позиция (номер символа), первого найденого совпадения с шаблоном $substring, в строке $string |
expr substr $string $position $length | Извлечение $length символов из строки $string, начиная с позиции $position |
expr match "$string" '\($substring\)' | Извлечение подстроки с начала строки $string, совпадающей с шаблоном $substring* |
expr "$string" : '\($substring\)' | Извлечение подстроки с начала строки $string, совпадающей с шаблоном $substring* |
expr match "$string" '.*\($substring\)' | Извлечение подстроки с конца строки $string, совпадающей с шаблоном $substring* |
expr "$string" : '.*\($substring\)' | Извлечение подстроки с конца строки $string, совпадающей с шаблоном $substring* |
* Где $substring -- регулярное выражение.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |


