Co oznacza „$ {- # * i}”! = „$ -”?

37

W /etc/profilewidzę tak:

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

Co ${-#*i}znaczy Nie mogę znaleźć definicji rozszerzania parametru rozpoczynającego się ${-.

Pete
źródło

Odpowiedzi:

40

$-to bieżące flagi opcji ustawione przez samą powłokę, podczas wywołania lub za pomocą setwbudowanego polecenia:

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

"${-#*i}"jest składnią do usuwania ciągów: (z dokumentacji POSIX )

$ {parametr # [słowo]}

Usuń najmniejszy wzór prefiksu. Słowo należy rozwinąć, aby uzyskać wzór. Rozszerzanie parametru powinno następnie skutkować parametrem, przy czym najmniejsza część prefiksu jest dopasowana do wzorca usuniętego. Jeśli występuje, słowo nie może zaczynać się od cudzysłowu „#”.

$ {parametr ## [słowo]}

Usuń największy wzór prefiksu. Słowo należy rozwinąć, aby uzyskać wzór. Rozszerzanie parametru powinno następnie skutkować parametrem, przy czym największą część prefiksu dopasowuje wzorzec usunięty.

Więc ${-#*i}usuń najkrótszy ciąg do pierwszego iznaku:

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

W twoim przypadku if [ "${-#*i}" != "$-" ]sprawdzenie, czy twoja powłoka jest interaktywna, czy nie.

Cuonglm
źródło
23

Istnieje parametr powłoki $-. W moim przypadku:

$ echo $-
himB

${-}jest taki sam jak $-dokładnie tak samo jak ${foo}jest taki sam jak $foo.

#*ioznacza: Usuń (tak mało, jak to możliwe; tutaj nie robi różnicy) od początku wartości zmiennej do (włącznie) pierwszej i.

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

Innymi słowy: [ "${-#*i}" != "$-" ]sprawdza, czy iwartość jest $-zawarta w zmiennej, to znaczy sprawdza, czy powłoka jest interaktywna.

Innymi słowy, jest to skomplikowany i niekompatybilny z Bourne'em sposób pisania:

case $- in
  *i*) ...;;
  *) ...;;
esac
Hauke ​​Laging
źródło
4
To jest POSIX zgodne , choć.
grawitacja