Czy jest możliwe, aby istniała powłoka logowania, która nie jest interaktywna?

11

Interpretując ten schemat blokowy

wprowadź opis zdjęcia tutaj

Odkryłem, że w man bash:

Kiedy bash jest wywoływany jako interaktywna powłoka logowania lub jako nieinteraktywna powłoka z opcją --login, najpierw czyta i wykonuje polecenia z pliku / etc / profile, jeśli plik ten istnieje.

Oznacza to, że interaktywne powłoki logowania zostały odczytane /etc/profile(bez opcji --noprofile)

Również nieinteraktywne powłoki z opcją --loginodczytu/etc/profile

Wydaje się, że pozostawia kilka możliwych powłok logowania (w których $0zaczyna się od a -), które nieinteraktywne (uruchamianie skryptu, być może tak proste jak date) mogą nie czytać (źródło) /etc/profile.

Aby potwierdzić lub odrzucić ten pomysł:

Najpierw próbowałem użyć su -l -, który uruchamia powłokę logowania -jako pierwszy znak, ale nie udało mi się uczynić go nieinteraktywnym (i być w stanie przedstawić testy, aby go sondować).

Wołanie czegoś takiego

$ bash -c 'date' -bash

Nie zgłasza się jako powłoka logowania (nawet jeśli pierwszym znakiem jest a -).

Spróbuj tego, aby ujawnić szczegóły:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016

$0Ma -jako pierwszego znaku, nie ma i(interaktywna) w wartości $-, ale to nie jest zgłaszane jako login_shell(-u). W tym przypadku / etc / profil nie został odczytany, ale nie jestem pewien, czy jest to właściwy test.


Jest też wzmianka o „rzadkich muszli nieinteraktywny login” w tej odpowiedzi nie będąc wystarczająco specyficzne dla tej kwestii.


Zawarcie tego człowieka jest to, że /etc/profilezawsze czytać.

Przeczytaj tabelę podsumowań: czyta się zarówno interaktywne, jak i nieinteraktywne powłoki logowania /etc/profile


A jeśli przykłady z tej strony są poprawne:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`

Test przeczytanych exec su - bob -c 'env'raportów /etc/profile.


W skrócie:

Czy można mieć nieinteraktywną powłokę logowania (nie wywoływaną przez --login lub -l)?

A jeśli to prawda, czy to czyta /etc/profileplik?

Jeśli powyższe jest prawdziwe, musimy stwierdzić, że WSZYSTKIE powłoki logowania [interaktywne (lub nie)] czytają / etc / profile (bez --noprofileopcji).

Uwaga: aby wykryć, że plik / etc / profile jest odczytywany, po prostu dodaj na samym początku pliku następujące polecenie:

echo "'/etc/profile' is being read"
Społeczność
źródło

Odpowiedzi:

2

Nieinteraktywna powłoka logowania jest niezwykła, ale możliwa. Jeśli uruchomisz powłokę z zerowym argumentem (który zwykle jest nazwą pliku wykonywalnego) ustawionym na ciąg rozpoczynający się na a -, jest to powłoka logowania, niezależnie od tego, czy jest interaktywna, czy nie.

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB

Twoja próba bash -c date -bashnie zadziałała, ponieważ nie oznacza to, że powłoka jest powłoką logowania: argument zerowy to bashnie -bash. Po uruchomieniu bash ustawia zmienną $0na -bashzamiast zerowego argumentu, ale argument zerowy jest najważniejszy.

Możesz uruchomić nieinteraktywną powłokę logowania za pomocą su -llub su -, ale musisz zadbać o to, aby standardowe wejście nie było terminalem, podczas gdy nadal możesz być autoryzowany (bez konieczności wpisywania hasła lub ustalania hasła na początku Wejście). Sudo: może być łatwiejsze sudo truedo uruchomienia, aby uzyskać poświadczenie obecności, a następnie, gdy poświadczenie jest nadal ważne, uruchom echo 'shopt -p login_shell; echo $-' | sudo -i.

Zobacz także Różnica między powłoką logowania a powłoką niezalogowaną?

Gilles „SO- przestań być zły”
źródło
4

Widziałem graficzne środowiska logowania, które:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

lub odpowiednik:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

Aby plik inicjujący sesję (jak w ~/.profileprzypadku powłok podobnych do Bourne'a (i odpowiadających im w /etcniektórych)) został odczytany i zastosowany.

Pierwszy nie działa ze wszystkimi powłokami. -ljest obsługiwany przez dużą liczbę powłok, ale nie wszystkie, a na niektórych, takich jak csh/ tcsh, nie można używać z -c. Pierwszy znak argv[0]bytu -jest jednak rozumiany przez wszystkie powłoki, ponieważ loginużywa ich, aby powiedzieć tym powłokom, że są powłokami logowania.

W drugim przypadku stdin tej powłoki jest czymś innym niż ttyurządzenie ( <<jest implementowany przez tymczasowy zwykły plik lub potok w zależności od powłoki), więc powłoka nie jest interaktywna (definicja interaktywnego bycia, gdy człowiek wchodzi w interakcję z tym).

Stéphane Chazelas
źródło
Pierwszy korzysta z --loginopcji. Po drugie, jeśli tak, to exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"dostaję (zakodowane w C qoutes), $'/etc/profile read\nshopt -s login_shell\nbash himBH'więc jest to login, ale interaktywny. Potrzebujemy loginu i nieinteraktywności . Czego mi brakuje?
@sorontar, z <<<"$-", który $-jest rozszerzany przez powłokę wywołującą z powodu podwójnych cudzysłowów. Wywołana powłoka nie jest interaktywna, ponieważ jej standardowe wejście nie jest tty.
Stéphane Chazelas,
Ach, tak, masz rację, Sir. Jednak poprawiając błąd, możemy to zrobić: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFaby uzyskać to potwierdzenie: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Tak, tak, możliwa jest nieinteraktywna powłoka logowania i nadal jest ona czytana /etc/profile. Czy powinniśmy stwierdzić, że WSZYSTKIE powłoki logowania zostały odczytane /etc/profile?
ksh wyjaśnia, że ​​jest to nieinteraktywna powłoka logowania , spróbuj exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF:).
1
@sorontar, myślę, że można oczekiwać, że większość implementacji powłoki przeczyta pliki inicjujące sesję, gdy zostaną wywołane jako powłoki logowania. To, jakie są, zależy od implementacji i wersji powłoki. W przypadku bashobsługi plików startowych IMO jest dość popsutym, zauważysz, że niektóre systemy załatały go, aby zachować bardziej rozsądne zachowanie, dodając jeszcze więcej zmian.
Stéphane Chazelas,
3

Tak, możliwe są nieinteraktywne powłoki logowania

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$
Stephen Harris
źródło
Która jest podobna do tej uproszczonej: su -c 'echo hello' -. Który, aby sprawdzić, co nam potrzeba, powinien być zapisany jako: su -c 'echo $0 $-; shopt -p login_shell' -aby uzyskać tę odpowiedź potwierdzającą (zakodowany w cudzysłowie C): $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Potwierdza to, że nieinteraktywna powłoka logowania została wyliczona i podczas tego procesu odczytano / etc / profile. Dzięki.
0

Czy można mieć nieinteraktywną powłokę logowania (nie wywoływaną przez --login lub -l)?

TAK.

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

Zauważ jednak, że /etc/profilenie byłby używany w przypadku powłoki interakcyjnej, chyba że --loginpodany zostanie argument.

Typowym idiomem wywołującym nieinteraktywną powłokę logowania jest:

$ su - someuser -c somecommand

Ale cierpi to na fakt, że /etc/profilenie zostanie stracony.

Można zmienić to zachowanie, ale wymaga to dostosowania kodu źródłowego Bash w czasie kompilacji poprzez odznaczenie opcji znalezionej w config-top.h :

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

Kiedy badałem suanomalię , odkryłem, że inne pociski, w tym zshi dashnie mają tej rozbieżności.

rozgwiazdy
źródło