Что означает ${- #*i} в скрипте оболочки?
В файле /etc/profile
на CentOS 6 есть цикл for:
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null 2>&1
fi
fi
done
Что означает ${-#*i}
в приведенном выше цикле for?
Спасибо за любую помощь.
3 ответа:
$-
означает флаги оболочки.
${-#*i}
означает флаги оболочки минус первое совпадение*i
.Если эти два не равны, то оболочка считается интерактивной (флаг
i
присутствует).
Смотрите верхний ответ на что означает " ${- #*i}"!= "$- "значит? on Unix & Linux by cuonglm :
$-
является ли текущая опция флагами, установленными самой оболочкой, при вызове, или с помощью командыset
builtin:$ echo $- himBH $ set -a $ echo $- ahimBH
"${-#*i}"
синтаксис для удаления строки: (из POSIX документация )${параметр#[слово]}
Удалить Наименьший Шаблон Префикса. То слово должно быть расширено, чтобы произвести шаблон. Расширение параметра должно тогда привести к параметру, с наименьшей частью префикса, соответствующей шаблону удаленный.
Если присутствует, слово не должно начинаться с без кавычек '
#
'.${параметр##[слово]}
Удалить Самый Большой Шаблон Префикса. Слово должно быть расширено, чтобы произвести шаблон. Расширение параметра должно тогда привести к параметру, с наибольшая часть префикса соответствует удаленному шаблону.
Итак,
${-#*i}
удалите самую короткую строку до первого символаi
:enter code here $ echo "${-#*i}" mBH
В вашем случае,
if [ "${-#*i}" != "$-" ]
проверка, является ли ваша оболочка интерактивно или нет.
Tl; dr:
Условный
[ "${-#*i}" != "$-" ]
вычисляется как логический true , если текущая оболочка интерактивна, в этом случае код выхода устанавливается в0
, сигнализируя true, что приводит к выполнению ветвиthen
оператора enclosingif
.Условный и код в вопросе в целом намеренно используют только POSIX-совместимый синтаксис и команды языка оболочки чтобы быть portable (работа со всеми POSIX- совместимыми оболочками, которые могут действовать как
/bin/sh
).обратите внимание, что если
bash
можно было бы принять за оболочку, например, то то же самое условное условие можно было бы более читабельно выразить как[[ $- == *i* ]]
Объяснение
${-#*i}
является расширением параметра , которое удаляет самый короткий префикс (#
), соответствующий шаблону*i
из значения именованного параметра$-
(именованным параметром является чаще всего называется переменной ).
$-
является специальным параметром , который (ссылка и курсив добавлены):Расширяется до текущегопараметра флагов (однобуквенные имена параметров, объединенные в строку ), как указано при вызове, специальной встроенной командой set или неявно оболочкой.
интерактивная оболочка неявно добавляет флаг опции
i
к значению$-
; другими словами: наличие буквыi
в значении$-
означает, что оболочка под рукой является интерактивной, и, наоборот, отсутствиеi
означает, что оболочка является неинтерактивной.Таким образом, при расширении параметра
${-#*i}
шаблон*i
будет совпадать только внутри значения$-
, если присутствуетi
, и, если это так, то в силу удаления того, что*i
совпало, возвращает a подстрока (суффикс, в данном случае)$-
.
Другими словами: только в интерактивной оболочке${-#*i}
не равно$-
, потому что в неинтерактивной оболочке - из - за отсутствияi
- расширение параметра не имеет эффекта, и два операнда равны.
Что код в вопросе делает в целом:
Короче говоря: код использует скрипты оболочки, которые он находит в
/etc/profile.d
, чтобы инициализировать текущую оболочку; более конкретно:
Скрипты (файлы с именем
*.sh
), расположенные в каталоге/etc/profile.d
, которые читаются текущим пользователем (-r
), передаются в.
(точка) утилиты по очереди, в алфавитном порядке. Утилита dot выполняет команды из каждого файла в текущей оболочке , как правило, для определения псевдонимов, функций и переменных окружения. Это обычно известно как sourcing a файл.выходные данные , создаваемые каждым исходным скриптом, обрабатываются по-разному в зависимости от того, является ли текущая оболочка интерактивной или нет:
интерактивная оболочка : выходные данные передаются через (будут видны в интерактивной оболочке).
неинтерактивная оболочка : выход подавлен (
>/dev/null 2>&1
является ли POSIX-совместимым способом заставить замолчать как stdout, так и поток stderr).