NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.06k stars 14.12k forks source link

`~/.profile` never gets called #5200

Closed jraygauthier closed 2 years ago

jraygauthier commented 9 years ago

Where should I perform my user profile environment setup then? Searched options, but there seemed to be no options for user specific environment setup.

Attempted something funky like:

  environment.extraInit = 
    ''
    if [-e $HOME/.profile] then;
        . $HOME/.profile
    fi  
    '';

in configuration.nix. It simply crashed my sudo command and did not source ~/.profiles. As a result, reverted to the previous generation.

Feels like it would be much simpler to have .profile called as in many other linux distros.

I want user installed packages to be based on my nixpkgs git repository while keeping 14.04's stability for the system. However, import <nixpkgs> directive uses the root user's channel instead of the nixpkgs repository tucked in .nix-defexpr/nixpkgs/ while nix-env do use my repository. Setting NIX_PATH however seemed to be recognized perfectly by the import command. Hence the need get a permanent alteration of user profile's environment.

I actually do not plan in the short term to upgrade my system to something unstable. Any possible workaround?

bjornfor commented 9 years ago

~/.profile is read only by login shells, not regular (interactive) shells. (Just tested this.) How about using ~/.bashrc?

For more info about what dotfiles bash executes commands from, see "man bash" and look for the INVOCATION section.

jraygauthier commented 9 years ago

You're indeed right. I concur that .profile is indeed sourced by login shell and that .bashrc is sourced by my current shell. So knowing that, a solution was to have the following .bashrc:

#!/bin/sh

if [ -e $HOME/.profile ] 
then
    . $HOME/.profile
fi

I realize that I'm used to get this kind of behavior when I use a Ubuntu distro whose shell default behavior is to call .profile which in turn calls .bashrc if shell is bash. I'm not sure what is the usual behavior for other distros in that regard.

vcunat commented 9 years ago

What bash does is indeed explained in man bash, and it's probably the same on any distro. (I'm not sure about Debian-based ones where the default shell is not bash.)

I believe the general intention is that ~/.profile gets sourced by login shells, and the environment subsequently gets passed to all child processes (including all usual shells).

This issue seems a misunderstanding to me (and not NixOS-specific anyway).

jraygauthier commented 9 years ago

It may indeed be a misunderstanding of sort. However, the following

subsequently gets passed to all child processes (including all usual shells)

is not occurring for some reason. When in a login shell, I indeed get the proper environment established by .profile. However, after login (in desktop manager xfce in that instance), when I launch a new terminal, the terminal does not get the proper environment as you suggest it should. It would mean that none of the launched application gets the environment defined by .profile.

On the man bash page, I could read the following:

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

~/.bash_profile or ~/.bash_login are not part of my home directory.

The behavior I get is as if the --noprofile option is passed systematically to bash.

In any event, I already have a solution. However, it seem pretty unusual behavior to me.

wmertens commented 9 years ago

@jraygauthier so you want 14.04 for your system and unstable for your nix-env? That should work just fine if the channels are set up that way for your user and root. Doesn't it?

vcunat commented 9 years ago

@jraygauthier: You do EXPORT the defined variables in your ~/.profile, don't you?

It's normal that ~/.bash_* are not in your home. When you create them, the will be used.

jraygauthier commented 9 years ago

@wmertens

so you want 14.04 for your system and unstable for your nix-env?

Yes that's it.

That should work just fine if the channels are set up that way for your user and root. Doesn't it?

It work pretty fine now that I can define user env. This is pretty much the same kind of context as when I used nix on top of Ubuntu (stable os + unstable pure pkg mgr).The need for env is merely because I use the nixpkgs repository in stead of channels as a package source.

@vcunat

You do EXPORT the defined variables in your ~/.profile, don't you?

Yes yes. For sure.

It's normal that ~/.bash_* are not in your home. When you create them, the will be used.

Yes I mentioned those only to make it clear that it couldn't be one of these that steals .profile's turn as a fallback env script.

vcunat commented 9 years ago

Hmm, I see that we do not source ~/.profile when starting an X session. We source /etc/profile and ~/.xprofile. I actually assumed that ~/.profile is supposed to always be sourced... does anyone know if there's some kind of UNIX or whatever documentation for these? Such things always seem so ad-hoc and confusing to me.

aragnon commented 9 years ago

.xprofile should not source .profile. That should be left to the user. In short, .xprofile and .profile should be unrelated. I also think these discussions should not be done here. I suggest we close this issue, because it's really just the ignorance of the issue starter which is the problem here.

jraygauthier commented 9 years ago

@aragnon: Pretty quick to call on ignorance of the issuer. However, unless proven otherwise (could it be related to my desktop environment) it still stands that ~.profile does not actually influence my user shell environments (except for pre login shell). Now, what we want to know is whether this is expected or not according to linux standard way of doing things. If not, this is an issue. Only otherwise it isn't.

As you suggest, I'm no linux expert but it is pretty counter intuitive that I get a greater set of environment variables pre-login than post-login. It seems at first glance that it should be the other way around.

jraygauthier commented 9 years ago

The following gives a thorough answer to the question.

http://superuser.com/questions/183870/difference-between-bashrc-and-bash-profile/183980#183980

On modern unices, there's an added complication related to ~/.profile. If you log in in a graphical environment (that is, if the program where you type your password is running in graphics mode), you don't automatically get a login shell that reads ~/.profile. Depending on the graphical login program, on the window manager or desktop environment you run afterwards, and on how your distribution configured these programs, your ~/.profile may or may not be read. If it's not, there's usually another place where you can define environment variables and programs to launch when you log in, but there is unfortunately no standard location.

According to what is said, because my session manager is graphical (I use Slim) and thus not a login shell it may explain why ~/,profile is not sourced. I concur that ~/.profile is indeed sourced when I deactivate Slim.

This is indeed one of the quirky historical linux behavior that you should learn to know (and love?). As @aragnon said, this is unrelated to nixos (but now with proof and reference) and could be closed in my opinion.

jraygauthier commented 9 years ago

https://bbs.archlinux.org/viewtopic.php?id=174916

This explains possible workaround for my particular use case (slim + xfce4).

aragnon commented 9 years ago

@jraygauthier That's not proof, it's just another guy with an opinion.

jraygauthier commented 9 years ago

@aragnon right nothing formal but at least approved and annotated by others. This gives it some credit (in my opinion). Anyway, thanks everyone for helping me with that issue.

kirelagin commented 9 years ago

Personally I believe that ~/.profile is very important as it is the single place to export things like $PATH so that it gets set both in shells and in desktop environment. Indeed this depends on desktop manager configuration, distro etc. but I believe that desktop managers should source this file (lightdm does) and login shells should source it too (I had to do this myself for zsh but bash does this automatically if there is no bash-specific ~/.bash_profile).

listx commented 9 years ago

I use Slim as well and got bit by the "not reading ~/.profile" behavior. I'm using gpg-agent with services.xserver.startGnuPGAgent = true; 1 because I need to use a Yubikey for SSH logins. The magic one-liner command that gets everything working (after I log in to X) is:

gpg-connect-agent updatestartuptty /bye

. See 2. Without this line, the pinentry box never shows up in my X terminals when I invoke SSH to login to a box with my Yubikey. Here is a section of the gpg document explaining the need for this:

Note: in case the gpg-agent receives a signature request, the user might need to be prompted for a passphrase, which is necessary for decrypting the stored key. Since the ssh-agent protocol does not contain a mechanism for telling the agent on which display/terminal it is running, gpg-agent's ssh-support will use the TTY or X display where gpg-agent has been started.

I've looked at verbose outputs of ssh when trying to connect to the remote server with my Yubikey and indeed that server asks for a "signature request" --- because without that gpg-connect-agent command, it fails right after this point (ssh output):

debug3: sign_and_send_pubkey: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

. Now, I'd like to read ~/.profile one time (when I log in) to execute the command above, but as discussed in the previous comments, Slim never executes /bin/sh as a login shell, so this is a bit annoying. I do like Slim, and this is an upstream quirk, but still, I thought it was worth repeating here to break the myth that ~/.profile is always read because it is a "standard" location.

For my problem, I could just scrap startGnuPGAgent and invoke gpg-agent manually in my config somewhere, but as I'm using SLiM there is no easy way to say "run this one time on login" --- because it does not read ~/.profile (I mean, sure, I could write a hack around it, but I feel like it's a natural thing for the 'login shell' feature of shells). I've tried using /etc/profile (which is indeed run on login), but the problem is I need to call gpg-connect-agent much later. I've also tried using services.xserver.displayManager.sessionCommands but it also did not work.

kirelagin commented 9 years ago

Arguably the distribution (that is, NixOS in our case) is responsible for maintaining this kind of consistensy of user experience.

For example, Gentoo ensures that ~/.profile (and ~/.xprofile) are sourced by placing this in /usr/share/slim/Xsession

wmertens commented 9 years ago

:+1: for sourcing .profile on X login, there is no way the shell can detect that otherwise.

(or is there? what about instead executing the window manager from a login shell? I suppose that's up to the session manager? Perhaps this is a bug in there?)

On Sun, Jun 28, 2015, 10:03 AM Kirill Elagin notifications@github.com wrote:

Arguable the distribution (that is, NixOS in our case) is responsible for maintaining this kind of consistensy of user experience.

For example, Gentoo ensures that ~/.profile (and ~/.xprofile) are sourced by placing this https://github.com/gentoo/gentoo-portage-rsync-mirror/blob/master/x11-misc/slim/files/Xsession-r3#L12 in /usr/share/slim/Xsession

— Reply to this email directly or view it on GitHub https://github.com/NixOS/nixpkgs/issues/5200#issuecomment-116218562.

Wout. (typed on mobile, excuse terseness)

kirelagin commented 9 years ago

what about instead executing the window manager from a login shell? I suppose that's up to the session manager? Perhaps this is a bug in there?

This might be considered a bug in NixOS indeed, as the slim module executes shell without the -login flag. On the other hand, NixOS’s xsession sources /etc/profile itself and that might be the reason, why -login is ommited. See my comment in #8538 for details.

I believe this part of NixOS is somewhat old (2009/2010). The . /etc/profile line was added in 2012 to make gpg-agent work, as the commit message claims. So I’d say all this stuff is a little bit random and can be improved considerably.

vcunat commented 9 years ago

Is there some kind of UNIX-like documentation saying what is supposed to be sourced at what occasions?

edolstra commented 9 years ago

Why was this issue reopened? ~/.profile clearly does get sourced for interactive login shells, just as described in the bash manpage.

vcunat commented 9 years ago

The reason was: one might expect to get env from ~/.profile also if only using graphical login. Some distros (at least) ensure that, as reported above, but I know of no standard specifying whether it should be sourced (e.g. along with ~/.xprofile).

kirelagin commented 9 years ago

I don’t think there is something like a definition of .profile and how it should to be used. Basically, I think, it is safe to assume that the shell spawned by whatever desktop manager we use is a non-interactive login one, so that the rest is left to bash.

spinus commented 9 years ago

@kirelagin +1

chairmank commented 8 years ago

This issue relates to (at least) two overlapping questions:

  1. In which scenarios (interactive shell, login via display manager, etc.) do we expect ~/.profile be sourced?
  2. Do we expect the per-user ~/.profile to be automatically sourced after the system-wide /etc/profile?

I am agnostic about question (1). I observe that /etc/profile is read when I login. I don't care why or how this happens.

However, I am interested in question (2). Why is ~/.profile ignored even though /etc/profile is read? My naive expectation is that /etc/profile ought to automatically source ~/.profile.

To get this behavior, I updated my nix configuration to populate a /etc/profile.local file:

environment.etc."profile.local".text = 
  ''
  # /etc/profile.local: DO NOT EDIT - this file has been generated automatically.

  if test -f "$HOME/.profile"; then
    . "$HOME/.profile"
  fi
  '';

/etc/profile reads /etc/profile.local, if it exists (https://github.com/NixOS/nixpkgs/blob/3f417e627221f33d0f1807a01ae6749c71f7391f/nixos/modules/programs/bash/bash.nix#L164).

This is a kludgy workaround, but it's not as bad as sourcing ~/.profile in ~/.bashrc or another place, which is simply backwards.

I don't have an opinion about whether this ought to be the default behavior. If people want it, then I'll gladly make a pull request.

matthiasbeyer commented 7 years ago

I guess this issue can be closed, as 14.04 is long dead now @jraygauthier @chairmank

vcunat commented 7 years ago

I don't know of any evidence that the situation has changed since then.

I don't have any strong opinion on either way (.profile, .xprofile, etc). Perhaps if "most systems" use one way, it might be good to behave the same.

chairmank commented 7 years ago

I confirmed that the behavior is the same in a recent version of NixOS (maybe not bleeding edge, but the latest release in the 16.09 series). And the code looks the same:

https://github.com/NixOS/nixpkgs/blob/7c7e88b45e137d2f0458bae167ede9d5fe551df2/nixos/modules/programs/bash/bash.nix

I think that it would be good to change the environment.etc."profile".text value to include something like

        # Read per-user modifications.
        if test -f "$HOME/.profile"; then
          . "$HOME/.profile"
        fi

after the lines that source /etc/profile.local.

spy-tech commented 7 years ago

The reason why we should close this issue is, because exactly there is no standard which says that it needs to be done in this particular way.

Indeed as has been said earlier, but not quoted:

--noprofile Do not read either the system-wide startup file /etc/profile or any of the personal initialization files ~/.bash_profile, ~/.bash_login, or ~/.profile. By default, bash reads these files when it is invoked as a login shell (see INVOCATION below).

It's a waste of time to leave this issue open. Please close it @vcunat. I would do it myself, if I had the credentials to do so.

vcunat commented 7 years ago

To me it seems confusing at least. It would be nice if the behavior was at least described somewhere (like our docs), i.e. making our own standard – preferably in a way consistent with some other systems, but I don't even see a good particular place where to put the information.

kirelagin commented 7 years ago

I don’t think this issue can be closed until there is a definite answer to the question “Where does one put exports that are applied universally on login?” in the documentation.

FRidh commented 6 years ago

Note we should also consider the (future) scenario with Wayland, which doesn't source any of these files. https://unix.stackexchange.com/questions/317282/set-environment-variables-for-gnome-on-wayland-and-bash-on-virtual-terminals-or#326161

whoizit commented 5 years ago

I came across this problem. I cannot set the environment variables in the files ~/.bash_profile and ~/.profile as if they are not used. And I could not find a solution

cnnrro commented 4 years ago

Came across this issue as well.

Using this workaround, which seems to make sense to me, for the time being:

environment.loginShellInit = ''
    if [ -e $HOME/.profile ]
    then
        . $HOME/.profile
    fi
'';
stale[bot] commented 4 years ago

Thank you for your contributions.

This has been automatically marked as stale because it has had no activity for 180 days.

If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.

Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse.
  3. Ask on the #nixos channel on irc.freenode.net.
nixos-discourse commented 4 years ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/override-environment-variables-with-user-variable-in-gnome/8974/1

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

sersorrel commented 3 years ago

I just ran into this. I was confused by the note at the top of /etc/profile that reads "This file is read for login shells.": if the shell is a login shell, then it should be reading my ~/.profile too, but it doesn't. I am reasonably sure that e.g. Ubuntu sources ~/.profile by default in graphical sessions, too, and most of my Linux experience is on Ubuntu.

shashurup commented 2 years ago

On Arch LightDM sources ~/.profile which seem reasonable to me. On nix I have to duplicate the contents of my ~/.profile into ~/.xprofile which doesn't look like a good solution in general. I think that ~/.profile is intended to be a place where I can define variables for both graphical and cosole sessions.

kira-bruneau commented 2 years ago

The main problem here was that display managers don't source the login shell environment, a workaround has been applied in #185987.

We now source ~/.profile in xsessionWrapper, but I think we'll eventually want to generalize this to load the actual login shell environment for the given $SHELL. The way we have it hard-coded right now is intended to emulate the login shell environment for sh - which is what we were partially already doing by sourcing /etc/profile.