Zsh nie uderza ~ / .profile

142

Właśnie zainstalowałem zsh w moim systemie Ubuntu. Wygląda na to, że zsh nie wykonuje ~ / .profile przy init. O ile mi wiadomo, powinno to być automatyczne zachowanie. czego mi brakuje?

Shmichael
źródło

Odpowiedzi:

203

.profile vs. .zprofile

Zsh nie działa ~/.zprofile, ~/.profilegdy jest wywoływany jako powłoka logowania. Powodem jest to, że zsh ma wystarczająco dużo niezgodności ze standardowymi powłokami, aby łamać skrypty.

Zsh działa, ~/.profilejeśli jest wywoływany jako shlub ksh. Ale jeśli Twoim celem jest wyświetlenie monitu o zsh podczas logowania, to nie pomoże.

Możesz utworzyć /bin/shpowłokę logowania i dołączyć ją export SHELL=/bin/zshdo swojego ~/.profile. Następnie, gdy otworzysz terminal, terminal uruchomi zsh (z wyjątkiem kilku emulatorów terminali nie przestrzegających tego $SHELLustawienia). Ale nadal będziesz mieć, shgdy zalogujesz się przez ssh. Można temu zaradzić, dołączając exec zshna końcu ~/.profile(to zastępuje działającą powłokę przez zsh), ale musisz być ostrożny, aby to zrobić tylko dla interaktywnych logowań, a nie wtedy, gdy ~/.profilejest dołączony z innych skryptów, takich jak rozpoczęcie sesji X (dobra test to nazwa procesu nadrzędnego uzyskana przez ps -o comm= $PPID: jeśli jest sshdlub su, to jest to bezpieczne exec).

Najłatwiejszym rozwiązaniem zarówno do pracy z zsh, jak i run ~/.profilejest utworzenie ~/.zprofiletrybu, który przechodzi w tryb emulacji podczas działania ~/.profile:

emulate sh
. ~/.profile
emulate zsh

Jeśli masz dość niedawną wersję Zsh (na Ubuntu, to znaczy od czasu świadomego, myślę), możesz to uprościć emulate sh -c '. ~/.profile'.

.zprofile vs. .zshrc

Plik ~/.profilejest ładowany przez powłoki logowania . Powłoka logowania jest pierwszym procesem uruchamianym po zalogowaniu się w trybie tekstowym, na przykład w konsoli tekstowej lub przez ssh. Domyślnie na większości komputerów z Linuksem powłoka logowania jest bash, ale można ją zmienić za pomocą chshpolecenia lub innego narzędzia, takiego jak „Ustawienia użytkownika” w Ubuntu. Gdy jest to powłoka logowania, bash czyta, ~/.bash_profilejeśli istnieje, a ~/.profilepodczas gdy zsh tylko czyta ~/.zprofile(ponieważ jej składnia nie jest w pełni kompatybilna z tradycyjnym sh). W większości konfiguracji ~/.profilejest również ładowany przez skrypty uruchamiania sesji X podczas logowania w graficznym menedżerze wyświetlania.

Po uruchomieniu emulatora terminala i wyświetleniu monitu powłoki lub po jawnym uruchomieniu powłoki otrzymujesz powłokę, która nie jest powłoką logowania. Ponieważ ~/.profile(lub ~/.zprofile) dotyczy poleceń, które chcesz wykonać podczas logowania, powłoka niezalogowana nie odczytuje tego pliku. Zamiast tego, kiedy uruchamiasz interaktywny zsh, odczytuje ~/.zshrc. (Zsh czyta ~/.zshrcwe wszystkich interaktywnych powłokach, niezależnie od tego, czy są to powłoki do logowania, nie są; bash, o dziwo, nigdy nie czyta ~/.bashrcw powłokach do logowania.)

Zazwyczaj ~/.profilezawiera definicje zmiennych środowiskowych i może uruchamiać niektóre programy, które chcesz uruchomić raz podczas logowania lub na całą sesję; ~/.zshrczawiera rzeczy, które należy wykonać dla każdej instancji powłoki, takie jak aliasy i definicje funkcji, ustawienia opcji powłoki, ustawienia zakończenia, ustawienia monitów, powiązania klawiszy itp.

Gilles
źródło
Świetna odpowiedź! Stworzyłem ~ / .zprofile i umieściłem wiersz tak, jak sugerowałeś, ale wydaje się, że nic nie robi. Być może powinienem umieścić go w .zshrc?
shmichael
1
@shmichael: Biorąc pod uwagę twoją reakcję, mogłem nie zinterpretować twojego pytania tak, jak chciałeś. Czy druga sekcja dodana do mojej odpowiedzi pomaga?
Gilles
tak, traf w miejsce. Więc jeśli dobrze rozumiem, chciałbym np. Deklaracje PATH na .zprofile i aliasy na .zshrc.
shmichael
@ user1419674 Dziękujemy za korektę, ale nie dodawaj dziennika zmian do postów. Witryna ma wbudowaną historię zmian.
Gilles
68

Krótka odpowiedź dla osób niecierpliwych:

  1. ~/.profilenie jest ładowany zshprzy logowaniu.
  2. zshładuje ~/.zprofileprzy logowaniu.
  3. zshładuje się ~/.zshrcpodczas rozpoczynania nowej sesji terminala.

Potrzebujesz więcej informacji? Spójrz na doskonałą odpowiedź Gillesa!

Karl Morrison
źródło
Świetna odpowiedź. Właśnie tego potrzebujesz.
Django Reinhardt
21

Oprócz odpowiedzi Gillesa, z dość aktualną wersją zsh, możesz to zrobić:

[[ -e ~/.profile ]] && emulate sh -c 'source ~/.profile'

... Który będzie pozyskiwał plik .profile z działającym trybem sh w Zsh. I jest aktywny tylko podczas źródła. Nie musisz więc zapisywać bieżącego stanu opcji, aby odtworzyć go ponownie po zakupie.

Frank Terbeck
źródło
Mam to w moim ~ / .zprofile, ale z jakiegoś powodu instrukcje w ~ / .profile nie są dostępne w mojej powłoce. Ubuntu 15.04; zsh 5.0.7
friederbluemle
Trudno zdiagnozować bez kodu.
Frank Terbeck
Właśnie spróbowałem ponownie i wygląda na to, że teraz działa. Nie jestem pewien, czy w pewnym momencie zostało to naprawione lub co się stało. Wersja zsh to teraz 5.1.1.
friederbluemle
5

Mam .zprofilekompatybilny z .profile(zawiera tylko zmiany PATH), dlatego potrzebuję tylko:

ln -s .profile .zprofile
Igor Shubovych
źródło
0

Zsh dokumentacja mam pod ręką tylko wymienia /etc/profilei ~/.profiledla powłok zgłoszeniowych w sh / ksh trybie zgodności.

% zsh --version
zsh 4.3.10 
% cat ~/.profile
echo 'Running ~/.profile...'

Powłoka logowania w trybie macierzystym (zaczyna się od argv [0] -) nie używa ~/.profile(będzie ~/.zprofilejednak używać ):

% zsh -c 'exec -a -zsh zsh' </dev/null

(brak wyników)

SH / KSH Zgodność trybu logowania muszle wykorzystuje .profile:

% zsh -c 'exec -a -sh zsh' </dev/null
Running ~/.profile...
% zsh -c 'exec -a -ksh zsh' </dev/null
Running ~/.profile...
Chris Johnsen
źródło