O que significa "${-#*i}" != "$-"?

O que significa "${-#*i}" != "$-"?

Em /etc/profileeu vejo isso:

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

O que ${-#*i}significa. Não consigo encontrar uma definição de uma expansão de parâmetro começando ${-.

Responder1

$-são os sinalizadores de opção atuais definidos pelo próprio shell, na invocação ou usando o setcomando interno:

$ echo $-
himBH
$ set -a
$ echo $-
ahimBH

"${-#*i}"é a sintaxe para remoção de string: (deDocumentação POSIX)

${parâmetro#[palavra]}

Remova o menor padrão de prefixo. A palavra deve ser expandida para produzir um padrão. A expansão do parâmetro resultará então em parâmetro, com a menor parte do prefixo correspondente ao padrão excluída. Se presente, a palavra não deve começar com '#' sem aspas.

${parâmetro##[palavra]}

Remova o maior padrão de prefixo. A palavra deve ser expandida para produzir um padrão. A expansão do parâmetro resultará então em parâmetro, com a maior parte do prefixo correspondente ao padrão excluída.

Portanto, ${-#*i}remova a string mais curta até o primeiro icaractere:

$ echo "${-#*i}"
mBH

No seu caso, if [ "${-#*i}" != "$-" ]verificando se o seu shell é interativo ou não.

Responder2

Existe um parâmetro shell $-. No meu caso:

$ echo $-
himB

${-}é igual a $-exatamente ${foo}igual a $foo.

#*isignifica: Excluir (o mínimo possível; não faz diferença aqui) desde o início do valor da variável até (incluindo) o primeiro i.

$ echo "${-#*i}"
mB

Ou seja: [ "${-#*i}" != "$-" ]verifica se existe um ino valor da $-variável, ou seja, verifica se o shell é interativo.

Em outras palavras, é uma maneira complicada e não compatível com Bourne de escrever:

case $- in
  *i*) ...;;
  *) ...;;
esac

informação relacionada