Ответ 1
$-
означает флаги оболочки.
${-#*i}
означает флаги оболочки минус первое совпадение *i
.
Если эти два значения не равны, оболочка считается интерактивной (присутствует флаг 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}
в приведенном выше для цикла?
Спасибо за любую помощь.
$-
означает флаги оболочки.
${-#*i}
означает флаги оболочки минус первое совпадение *i
.
Если эти два значения не равны, оболочка считается интерактивной (присутствует флаг i
).
Посмотрите лучший ответ на Что означает "$ {- # * i}" != "$ -" означает? на Unix и Linux cuonglm:
$-
- это текущие флаги опций, установленные самой оболочкой, при вызове, или с помощью встроенной командыset
:$ echo $- himBH $ set -a $ echo $- ahimBH
"${-#*i}"
- синтаксис для удаления строки: (из POSIX документация)${параметр # [слово]}
Удалить малый шаблон префикса. Слово должно быть расширено для производства шаблон. Затем расширение параметра должно приводить к параметру, с наименьшей частью префикса, соответствующей шаблону удален.
Если присутствует, слово не должно начинаться с некорректного "
#
".${параметр ## [слово]}
Удалить самый большой шаблон префикса. Слово должно быть расширено для создания шаблон. Затем расширение параметра должно приводить к параметру с самая большая часть префикса, соответствующая удалению шаблона.
Итак
${-#*i}
удалите кратчайшую строку до первого символаi
:enter code here $ echo "${-#*i}" mBH
В вашем случае
if [ "${-#*i}" != "$-" ]
проверка, если ваша оболочка интерактивный или нет.
TL;DR:
Условный [ "${-#*i}" != "$-" ]
вычисляет логическое значение true, если текущая оболочка является интерактивной, и в этом случае код завершения устанавливается равным 0
, сигнализирующий true, что вызывает заключенный if
оператор then
для выполнения.
Условный и код в вопросе в целом намеренно используют только Синтаксис и команды на языке синтаксиса, совместимые с POSIX, чтобы быть переносимым (работа со всеми совместимыми с POSIX оболочками, которые могут действовать как /bin/sh
).
Обратите внимание, что если bash
можно считать оболочкой, например, то же условное выражение может быть более читаемо выражено как
[[ $- == *i* ]]
${-#*i}
- это расширение , которое удаляет кратчайший префикс (#
), который соответствует pattern *i
из значения именованного параметра $-
(именованный параметр чаще называют переменной).
$-
является специальным параметром, который (ссылка и выделение добавлено):
расширяется до текущего option flags (имена однобуквенных опций, объединенных в строку), как указано при вызове, заданной специальной встроенной командой или неявно оболочкой.
Интерактивная оболочка неявно добавляет флаг опции i
к значению $-
; Другими словами: наличие буквы i
в значении $-
означает, что оболочка под рукой является интерактивной, и, наоборот, отсутствие i
подразумевает, что оболочка неинтерактивна.
Таким образом, при расширении параметра ${-#*i}
шаблон *i
будет соответствовать только внутри значения $-
, если присутствует i
, и, если это так, в силу удаления того, что *i
сопоставлено, возвращает подстроку (суффикс, в данном случае) $-
.
Другими словами: только в интерактивной оболочке ${-#*i}
не равно $-
, потому что в неинтерактивной оболочке - из-за отсутствия i
- расширение параметра не действует, и оба операнда равны.
Вкратце: код использует сценарии оболочки, которые он находит в /etc/profile.d
для инициализации текущей оболочки; более конкретно:
Сценарии (файлы с именем *.sh
), расположенные в каталоге /etc/profile.d
, которые читаются текущим пользователем (-r
), передаются в .
(точка), в алфавитном порядке. Утилита dot выполняет команды из каждого файла в текущей оболочке, как правило, для определения псевдонимов, функций и переменных среды. Это обычно известно как поиск файла.
Вывод, созданный каждым источником script, обрабатывается по-разному в зависимости от того, является ли текущая оболочка интерактивной или нет:
интерактивная оболочка: вывод передается (будет отображаться в интерактивной оболочке).
неинтерактивная оболочка: выход подавляется (>/dev/null 2>&1
- это способ, совместимый с POSIX, для молчания как stdout, так и stderr).