Что означает ${- #*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 :
$-является ли текущая опция флагами, установленными самой оболочкой, при вызове, или с помощью командыsetbuiltin:$ 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).