Open amckinlay opened 4 years ago
If they keep updating these files, perhaps we should file an Apple Feedback report asking them to add /etc/bashrc.d/
and /etc/zshrc.d
folders whose contents get sourced by the default scripts? This way we can add configuration there that won't get overridden.
Beyond that, the only automatic solution that comes to mind would be to have nix-daemon
check these files on launch and re-add the Nix block if it's missing.
I have done a few days before the upgrade to Catalina 10.15.6... and today I wanted to install something to discover that my nix installation was gone! Well after some research, I found that the /nix was still there, but everything else was gone... no nix-env command nothing! So after cursing a lot... I search until I found this thread... I would like also that this problem to solved... For the moment, I have put on my 2 users the following lines in the ~/.profile
# Nix
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
# End Nix
So I don't care if the /etc/zshrc is or not overwritten in the future... I agree this is a bad solution, but at least for the time being my workaround...
I filed feedback for Apple (FB8181728). In the meantime, nix-daemon
will need to learn how to modify the files appropriately on launch.
The zsh case seems to have been fixed (but not released yet) in the course of #3456. I haven't observed this same issue with bash shell files.
Edit: this had its own problems and was reverted.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
I marked this as stale due to inactivity. → More info
I'm still seeing this issue as of Nix 2.3.15 and Big Sur 11.5.2. The workaround is to re-add the following to /etc/zshrc
:
# Nix
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
source '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
# End Nix
I'm still seeing this issue as of Nix 2.3.15 and Big Sur 11.5.2.
Edit: I see in matrix that #3608 caused its own problems documented in #4169, so I guess a release would actually be a step in the wrong direction atm... Striking through the parts that may not actually be much help...
FWIW this is roughly expected:
~I would try manually migrating. I think you'd just need to create /etc/zshenv if it doesn't exist, move your source line there, and verify it works.~
~Also: brownie points if you (or maybe any zsh user who hasn't taken 11.5.2 yet?) remember to report back here or in #3608 if this migration helps you dodge this problem.~
can't we just patch zsh to use different rcfile paths? users can then set the patched zsh as their shell with nix-darwin
@ggPeti I assume it's ideal if it still works without Nix-darwin, but tbh I have no clue how big the set of (Nix + zsh - nix-darwin) uses is.
I recently stumbled on a reference to someone saying they'd taken an update and had the update leave their modified items in place, and add the replaced items to the Relocated Items directory.
I have a spare laptop on the beta release channel and wanted to try this out, so I took an update on it this afternoon to 11.5 and noticed two things:
/etc/bashrc
on this update--it just placed the "official" bashrc at Relocated\ Items/Configuration/private/etc/bashrc.system_default
.I'm not sure if this means they're treating zsh init files differently since it's the default shell, or if it means they inadvertently left zshrc out of the list of files to respect instead of replace. Something to watch closely in the next few updates, I guess.
I recently stumbled on a reference to someone saying they'd taken an update and had the update leave their modified items in place, and add the replaced items to the Relocated Items directory.
I have a spare laptop on the beta release channel and wanted to try this out, so I took an update on it this afternoon to 11.5 and noticed two things:
- It did not displace
/etc/bashrc
on this update--it just placed the "official" bashrc atRelocated\ Items/Configuration/private/etc/bashrc.system_default
.- It did, however, still overwrite /etc/zshrc.
I'm not sure if this means they're treating zsh init files differently since it's the default shell, or if it means they inadvertently left zshrc out of the list of files to respect instead of replace. Something to watch closely in the next few updates, I guess.
I tried this with an update from 12.0 beta to 12.0.1 and, once again, zshrc was overwritten.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/nix-commands-missing-after-macos-12-1-version-upgrade/16679/5
And of course this happened again on 12.2. (@frlan)
Please deprecate nix on macOS.
... please don't?!?
Every macOS update breaks nix. It's clearly not ready for macOS.
When trying to debug this problem for myself, I think I was misled by the current documentation. For example, this discussion of environment variables
https://nixos.org/manual/nix/stable/installation/env-variables.html
assumes a single-user installation. (I think?) And because I don't have prefix/etc/profile.d/nix.sh
I thought my installation might be broken. Am I right in thinking there should be separate sections for single and multi user installations and the multi-user section should mention nix-daemon.sh instead of nix.sh?
assumes a single-user installation... Am I right in thinking there should be separate sections for single and multi user installations and the multi-user section should mention nix-daemon.sh instead of nix.sh?
Good catch. I think so. If none of the differences between the two scripts seem to fall within the scope of the current documentation, it might suffice to just say that each mode has a distinct script and list the path for each?
That sounds reasonable to me
Happened to me today, macOS Monterey 12.2 -> 12.3 update.
Fix that worked for me:
# 1. Remove backup files
sudo rm /etc/{bashrc,zshrc}.backup-before-nix
# 2. Run installation script again
sh <(curl -L https://nixos.org/nix/install)
# Doing 2. before 1. makes the installation script fail.
@thiagowfx You don't have to reinstall. As noted multiple times in the thread, you just need to re-add the profile/rc hook to /etc/bashrc or /etc/zshrc.
And because I don't have
prefix/etc/profile.d/nix.sh
I thought my installation might be broken.
Same for me. I "fixed" it by running
/nix/store/*-nix-2.*/bin/nix-env -iA nixpkgs.nix
Which creates all the same links in your per-user profile, but of course, that's only a viable workaround for a single user on a multi-user install.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/fixing-your-install-after-osx-upgrade/19339/6
Same issue on my side, while updating from Monterey 12.1 to Monterey 12.5 on a Apple M1 Pro...
Fixed by adding the following lines on /etc/zshrc
# Nix
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
# End Nix
Fixed by adding the following lines on
/etc/zshrc
how can i do if i have remove the pre-installed version, Now it can't install successful ........
Fixed by adding the following lines on
/etc/zshrc
how can i do if i have remove the pre-installed version, Now it can't install successful ........
@somebodyLi The instructions didn't say to remove this system file, so I don't know why you removed it.
/etc/zshrc.backup-before-nix
, all you need to do is sudo mv /etc/zshrc.backup-before-nix /etc/zshrc
(as the instructions say).This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/nix-install-breaks-after-every-macos-monterey-update/21353/4
I have encountered what I think is another flavour of this issue (https://github.com/NixOS/nix/issues/7106), except this time I lost /etc/fstab
on update and my nix volume was modified during the upgrade to mount /Volumes/Nix\ Store
instead of /nix
. This breaks all the symlinks. Trying to figure out what how to correctly change the mount point back to /nix
(just started looking because I just figured out roughly what was going on).
Edit: This was upgrading 12.5.1 to 12.6, btw
Edit 2: I was able to resolve the issue and think that it might have coincidentally lined up with an OS upgrade. The /etc
files might have been removed by multiple runs of the install script but there was no indication of an issue until a system restart, which changed the volume mount point. That is the new theory, at least.
For future reference this is what /etc/fstab
should look like:
#
# Warning - this file should only be modified with vifs(8)
#
# Failure to do so is unsupported and may be destructive.
#
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /nix apfs rw,noauto,nobrowse,suid,owners
With the appropriate UUID.
Edit 2: I was able to resolve the issue and think that it might have coincidentally lined up with an OS upgrade. The /etc files might have been removed by multiple runs of the install script but there was no indication of an issue until a system restart, which changed the volume mount point. That is the new theory, at least.
FWIW I'm currently on 12.6 and had no issue whatsover when upgrading to it (other than the usual /etc/zshrc
).
Yeah, I used https://gist.github.com/meeech/0b97a86f235d10bc4e2a1116eec38e7e#check-you-have-nix to help me get back to a working state. It was both /etc/synthetic.confg
and /etc/fstab
that I needed to re-create.
I just upgraded to macOS 13.1 (22C65), it seems /nix survived.
➜ ~ diskutil list | grep Nix
7: APFS Volume Nix Store 1.4 GB disk3s7
➜ ~ diskutil info disk3s7 | grep Mount
Mounted: Yes
Mount Point: /nix
Hence the only restoration really need is ~/.zshrc
or /etc/zshrc
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
@alphatownsman for me nix always survived but the /etc/zshrc
is overwritten in every update needing manual adding the shell hook back into this file to make it work again.
As an other issue noted https://github.com/NixOS/nix/issues/3456 we should use /etc/zshenv
which is global and loaded by default BUT not overwritten by an OS update since it does not exist by default.
Tested it and that way the shell hook survived the last macos update. No action was needed (adding sth back to /etc/zshrc
)
IMHO we should change the installer script to use /etc/zshenv
instead of /etc/zshrc
for mac
@FloThinksPi we tried zshenv but reverted because it causes its own problem. See https://github.com/NixOS/nix/issues/4169
Edit: but it's a fine approach for individuals who want their system binaries to have priority. This isn't the normal case, but I know there are at least a few people out there who prefer that behavior.
@abathur Dang! Yea i also dont want that prio of binaries.
Hm there must be a way to have the shell hook somewhere that does not get overwritten, brew
e.g. puts it in the users shell env by printing a snipped people have to add themselfs. Maybe we should just print the snipped in the installer too and let people figure out where to put the hook. Thats also how pyenv
and other tools which mess with the shell do it.
Docker does this also to the users ~/.zshrc but instead of printing it, inserts it on its own which i feel like many people would not like since i personally dont like a tool altering my versioned dotfiles.
source /Users/<username>/.docker/init-zsh.sh || true # Added by Docker Desktop
Anyway that way people would not expect the nix installer to manage that part and we could close the issue that way.
The issue is that we can't use /etc/zshenv
because the $PATH we set gets overriden by /etc/zprofile
.
Instead we use /etc/zshrc
, which gets overriden by macOS on upgrades.
There's a detailed explanation how the startup of zsh works: https://gist.github.com/Linerre/f11ad4a6a934dcf01ee8415c9457e7b2
The only solution I can think of is:
/nix/var/nix/profiles/default/bin
to /etc/paths
nix
check for __ETC_PROFILE_NIX_SOURCED=1
and if absent, tell the user to run a command that will populate /etc/zshrc
.Nix will still break, but the fix for the user is provided in a nice way.
I communicated this issue upstream to our devrel this past fall (it was passed along, but I haven't heard anything else).
One ~alternative solution I've seen suggested is either updating nix-daemon or installing a separate daemon that will fix-up if it goes missing.
Another is just caving and using ~/.zshrc.
I don't remember for sure, but we might also be able to try to pre-empt path_helper (which is what screws up the PATH if we use zshenv, and what processes /etc/paths and /etc/paths.d/*) by declaring a function in zshenv with its absolute path (/usr/libexec/path_helper), and then implementing it as a wrapper there that can ~fix the PATH it generates. (But I'm just assuming this is valid in zsh; function names with slashes are at least valid in bash).
~/.zshrc
means that it's very hard to support multi-user installs properly, so I'd be up for shoving it into nix-daemon.
Triaged in the Nix team meeting:
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/2023-03-03-nix-team-meeting-minutes-37/25998/1
Would using a LaunchDaemon be an alternative solution to modifying the fstab directly (for the fstab portion of the issue). Have looked at this as a possibility in in issue #7106 , though it is still a bit of an experiment.
For later travelers, I'm fairly certain that the macOS update did not remove your fstab. The fstab ~issue noted by a couple of late comments in this thread is a side effect of trying to fix the installation by re-running the installer (which is not currently idempotent) without completely uninstalling first.
If you run into the core problem here (macOS update overwriting the shell init hook for ZSH) and tried running the installer without uninstalling, you'll need follow the uninstall instructions before reinstalling it: https://nixos.org/manual/nix/stable/installation/installing-binary.html#macos
Edit: someone in matrix confirmed that they installed 13.3 on march 27 2023 and it did not remove fstab.
I'm responding here to part of a comment from another issue because it's more on-topic here. The relevant bit:
Edit: just looking at the zsh files and would one of the files such as /etc/zprofile by a suitable alternative, though again would need to check what files Apple indicates as being safe from overwrites?
I'm not really sure. If there's a problem with it, it'll probably be because zshrc files should get sourced for any interactive shell, while zprofile will only get sourced for login shells. If it is viable, I agree that we should get confirmation that updates don't clobber it before we try to change the installer.
It's a bit of an aside, but there has also been some mumbling (throughout this thread, and in the installer workgroup meetings) about Nix-side alternatives that roughly boil down to:
path_helper
in /etc/zprofile
will keep that from yielding any better options)BTW I decided to ask the question about zsh related files on StackExchange, and it looks like other people deal with the same headache, as part of their sysadmin work:
I experienced this upgrading from Ventura 13.3 to the beta Ventura 13.4. I can confirm the fix as mentioned above by many worked for me - appending the following to '/etc/zshrc':
# Nix
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
source '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
# End Nix
I had aliased so many commands to programs installed through Nix that zsh was unusable, I had to use bash to actually edit /etc/zshrc
.
@ajmas from a comment to the answer:
launchd task / cron task that checks for the required edits, exits quietly or removes itself if there's no work to do.
Something like this seems to be the only somewhat reliable option. Maybe nix-daemon itself could do that?
I see that the nix-daemon.sh
script prepends PATH items without checking to see if they're in PATH already. I know this is pretty common practice but the idea of duplicating PATH entries ad nauseam always bothered me so I wrote this Bash function to prepend but first eliminate the relevant entry from PATH if it's already there, making this operation idempotent. The function also works with other PATH-like variables such as LD_LIBRARY_PATH
etc.
# function to prepend paths in an idempotent way
prepend_path() {
local dir="${1%/}" # discard trailing slash
local var="${2:-PATH}"
if [ -z "$dir" ]; then
echo "Usage: prepend_path <path_to_prepend> [name_of_path_var]" >&2
return 2 # incorrect usage return code, may be an informal standard
fi
local newvalue=${!var}
[[ $newvalue =~ ^$dir: ]] && return # quit if value already starts with $dir
newvalue=${newvalue%:$dir} # remove $dir from end of path
newvalue=${newvalue//:$dir:/:} # remove $dir from middle of path
# prepend the new entry
export ${var}="$dir:$newvalue"
}
Hm there must be a way to have the shell hook somewhere that does not get overwritten, brew e.g. puts it in the users shell env by printing a snipped people have to add themselfs.
I run fish and well… colour me surprised that the Nix installation had messed with /etc/zshrc
and that a change in that file has an impact on my shell which is not zsh.
I think asking people to add it themselves to the shell they use is the way to go.
I have noticed that every once and a while
/Users/andrewmckinlay/.nix-profile/bin
and/nix/var/nix/profiles/default/bin
disappear from my$PATH
. The last time this happened, the hook nix installed was missing from/etc/zshrc
.Copying the following hook (copied from
/etc/bashrc
) to/etc/zshrc
and restarting the shell fixed everything again:My concern is that macOS updates will periodically overwrite
/etc/.zshrc
(and/etc/.bashrc
), requiring effort on my part to reinstall nix. For example, one macOS update overwrote the entire file to fix this misspelling:Both files are read-only anyway, should they really be written to by the nix installer?