Dlaczego „echo $ 0” daje inny wynik dla dwóch różnych terminali?

15

Otworzyłem terminal na Ubuntu za pomocą Ctrl+ Alt+ Ti innego terminalu, przechodząc do katalogu, a następnie klikając prawym przyciskiem myszy i wybierając „Otwórz w terminalu”.

Zrobiłem echo $0w obu przypadkach.

W pierwszym przypadku:

$ echo $0
-bash

W drugim przypadku:

$ echo $0
/bin/bash

Skąd ta różnica?

CodeBlue
źródło
$ 0 zwraca nazwę uruchomionego procesu.
Ramesh
Czy prowadzisz dwa terminale z innym użytkownikiem?
cuonglm
Używam tego samego użytkownika
CodeBlue
Czy w rzeczywistości są to różne emulatory terminali, czy tylko dwa wystąpienia tego samego emulatora terminali? Czy oba są domyślnym terminalem?
terdon

Odpowiedzi:

16

Jeśli wynikiem echo $0polecenia jest -bash, oznacza to, że bashzostał wywołany jako powłoka logowania. Jeśli dane wyjściowe są tylko bash, oznacza to, że nie jesteś zalogowany.

man bash mówi gdzieś w linii 126:

A  login shell is one whose first character of argument zero is a -, or 
one started with the --login option.

Zobacz więcej na ten temat: Różnica między powłoką logowania a powłoką niezalogowaną? .

Teraz, aby wyjaśnić, dlaczego dostajesz się /bin/bashw drugim przypadku, mogę powiedzieć, że program (w twoim przypadku menedżer plików, prawdopodobnie nautilus) lub skrypt może zmienić swój własny $0na coś innego. Jako przykład zobacz, co się dzieje z $0moim terminalem (cały czas ten sam terminal):

wprowadź opis zdjęcia tutaj

Radu Rădeanu
źródło
12

Różnica polega na sposobie ich uruchomienia. bash będzie inicjował się inaczej (odczytuje różne skrypty startowe) w zależności od argv [0]. Jeśli ciąg zaczyna się od myślnika -jak w in, -bashwówczas działa jako powłoka logowania, jeśli nie, będzie działać jako powłoka interaktywna. Może również działać jako powłoka nieinteraktywna (tj. W skrypcie powłoki).

Aby dowiedzieć się więcej, najlepiej przeczytać instrukcję, man bashrozdział ZAPROSZENIE.

X Tian
źródło
9

Powłoka jest uruchamiana podczas logowania, ale jest również uruchamiana przez programy takie jak makelub podczas uruchamiania skryptu powłoki, podczas pisania :shdo vilub tworzenia nowego okna terminala.

Oryginalnie powłoka wczytywała się ~/.profilepo zalogowaniu lub uruchomieniu su. Ten skrypt służy do ogłaszania, czy masz nowy e-mail, dostosowywania znaków kasowania i zabijania oraz ustawiania i eksportowania zmiennych TERM i PATH. Po uruchomieniu w prawie każdym innym kontekście powłoka nie czytała ~/.profile, ponieważ wykonanie większości tych czynności byłoby zbędne. Oczekiwano, że wyeksportowano wszystkie ważne zmienne powłoki do nowej powłoki.

Sposób powłoka wiedział, czy odczytywane ~/.profilebyło sprawdzenie, czy pierwszy znak argv[0], znany $0był '-'.

Począwszy od csh, wprowadzono aliasy. Aliasy nie zostały wyeksportowane do środowiska. cshzostał zaprojektowany do odczytu w dwóch różnych skryptach inicjujących. ~/.loginzostał odczytany tylko wtedy, gdy użytkownik się zalogował, a wskazówką, aby to zrobić, było argv[0]rozpoczęcie '-'. ~/.cshrcbył czytany przy każdym uruchomieniu powłoki. Ogólnie, umieszcza się aliasy ~/.cshrci wszystko inne w ~/.login. cshobsługiwane również ~/.logout, co w większości przypadków po prostu wyczyściło ekran i uruchomiło się fortune.

Inne pociski przyjęły te same funkcje. kshwczytywałoby ~/.kshrc, bashwczytywałoby się ~/.bashrc, a tam byłyby miejsca, w których należy umieścić definicje aliasów.

Krótko mówiąc, aplikacja, która spawnuje powłokę, decyduje, czy powinna to być „powłoka logowania”, w takim przypadku '-'na początku, czy zwykła powłoka. W większości przypadków powłoka, która ma być interaktywna, jest uruchamiana jako powłoka logowania, a powłoka służy tylko do uruchamiania niektórych poleceń, jako argumentów lub skryptu, a następnie wyjście jest zwykłą powłoką.

Ale wszystko zależy od kaprysu aplikacji, która uruchamia powłokę.

Mark Plotnick
źródło