runtime: dotnet command doesn't exist on macOS

@grosch commented on Sat May 18 2019

Issue Title

dotnet command doesn’t exist after installing SDK

General

I just went to https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/install and downloaded the SDK. It installed without any errors. I then closed all terminals and opened a new one, but the dotnet command doesn’t exist.

I’m on macOS Mojave 10.14.4


@CPoffWebster commented on Sat May 18 2019

I have the same issue. It seems to download fine on macOS High Sierra, but not on Mojave.


@grosch commented on Sat May 18 2019

Their installer is screwy. This will fix your issue:

sudo ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/

@CPoffWebster commented on Sat May 18 2019

Thank you this fixed the issue!


@karelz commented on Wed May 22 2019

@dagood any idea who could help fix this in our installers?


@leecow commented on Thu May 23 2019

The Mac installer does not create a symlink, it adds /usr/local/share/dotnet to PATH. We can discuss if changing the approach makes sense as well as try to figure out why PATH was not updated in this case.


@grosch commented on Thu May 23 2019

@leecow Updating the PATH is never the right thing to do. You have no idea how the system or the user’s environment is configured. Every time you add to the path, for example, the shell has to re-find everything. The path should be set one and only one one time for performance reasons.

Regardless, you’re making an assumption as well that I’m using Bash as my shell, for example. I hate bash, I’m using tcsh, and you’re not updating that. The proper way to install local software is to install it into /usr/local/bin, or ask the end user where it should be installed. Don’t try to have your software modify the path.


@leecow commented on Thu May 23 2019

Thanks for that feedback @grosch. We’ll have a look at making the change. Moving this issue to core-setup.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 15 (10 by maintainers)

Most upvoted comments

We should plan a switch away from path_helper. I’ve added untriaged label to bring this issue to triage to determine the appropriate timelines for the fix.

a “bad” .bash_profile can also cause this, or different non-standard shells that don’t support path_helper.

ain’t that a good enough reason by itself to favour symlinks over path_helper?

That comment was only meant as a reminder that I do think there’s plenty of justification to remove path_helper. 😄 Specifically: even though Catalina+ doesn’t seem to have this issue in its default state, I still think .NET should remove the dependency on path_helper even if support for pre-Catalina OSes is dropped in the future.

This was where I meant to make my opinion clear, in an earlier comment:

Still worth getting rid of our dependency on path_helper to make things simpler for everybody, IMO.

The only reason I know of that this hasn’t been changed yet is that nobody has been able to spend the time to develop the change and validate that it won’t break anyone.

After a fresh install of dotnet and vscode, build or debug tasks fail with the following error:

> Executing task: dotnet build /Users/ostwilkens/Projects/UnlimitedShaderForks2/UnlimitedShaderForks/UnlimitedShaderForks.csproj /property:GenerateFullPaths=true /consoleloggerparameters:NoSummary <

The terminal process failed to launch: Path to shell executable "dotnet" does not exist.

Terminal will be reused by tasks, press any key to close it.

Related: https://github.com/microsoft/vscode/issues/118460

I had this problem today. Mojave 10.14.6, with zsh as my login shell. zsh just never seems to run /etc/profile, so path_helper is never called, so dotnet doesn’t end up on the path.

Catalina has an /etc/zprofile that calls path_helper, presumably to fix this very issue, so I suspect the tools will straight away work fine on that.

For now, I’ve added a call to path_helper to my ~/.zshenv: test -x /usr/libexec/path_helper && eval $(/usr/libexec/path_helper -s). Now I can run dotnet without any messing about.

(This also magically made the Go tools appear on my path by default. Always annoyed me I’d had to do that manually. Now I know why.)

Thanks,

–Tom

I’m aware the Go and Mono installers are exceptions, I’m hoping that because they’re similar to .NET Core (Mono in particular), seeing the reasons for those decisions can help us understand what we’re dealing with. If there’s something nasty being avoided by using path_helper, I want to know.

As soon as someone sets their own path in their startup files, and doesn’t append to what the system gave them, you lose any benefit to using path_helper.

I think this is a pretty compelling reason to switch. It (or something else about path_helper) probably caused https://github.com/dotnet/core/issues/2693, and who knows how much trouble for others.


If you’re really going to look at changing your installer, I’d ask you also look into why you’re writing to /usr/local/share in the first place and even worse putting a binary at the same level as files and directories vs in a bin directory.

There’s no need to batch that feedback up with this issue, IMO. Leading up to 3.0, as long as a change is good I don’t think there’s a huge amount of momentum to overcome. If you don’t mind creating a new issue with some specifics about the dangers with the current layout I think that’s a good place to start. (I think Core-Setup is the right place for that discussion too, but I think it’ll be a larger one.)

There’s info about the current layout at https://github.com/dotnet/designs/pull/58/files, although I don’t see that much info why some of the longstanding conventions exist.

First, to make sure everyone’s on the same page, the way this works right now is that the macOS .NET Core installer creates a file /etc/paths.d/dotnet that contains the install location. This allows the macOS tool path_helper to find it while spawning a new shell:

https://github.com/dotnet/core-setup/blob/e550056ab91de0b5c6b82518a99dab7ccc801f83/src/pkg/packaging/osx/sharedhost/scripts/postinstall#L9-L17

(This doesn’t appear to assume bash to me, but I wasn’t able to find any useful info about how tcsh in particular interacts with path_helper when I poked around.)

I traced this down to this PR: https://github.com/dotnet/cli/pull/840. Apparently we switched from symlinks to path_helper to work around a bug, not any reason I’d call significant. 😕

path_helper is apparently a controversial utility based on what I’m finding on the internet. At face value, making a symlink seems simpler and probably more normal, perhaps especially when comparing it against the Linux ecosystem.


There’s precedent, though, of other similar products using path_helper:

The Mono installer uses it at the moment: postinstall#L24-L34. The switch from symlinks to path_helper seems to have happened unfortunately without any description here: https://github.com/mono/bockbuild/commit/3e900296aa8eb7ef91fd6cf0b1b6f540c6242d74#diff-d4ed8cbf31db07014a6866e74f3f568b

Go also apparently currently uses path_helper: https://stackoverflow.com/q/38337790. There’s also a brief justification for using it in general:

because automatic software installation (and what’s more important UNinstallation) is much easier this way. Many Linux distros switch to .d directories for many configuration files (Apache 2.0 was AFAIK the first program to support this kind of stuff) because it makes administration much easier.


It seems like we should be able to depend on path_helper. I fully admit I most likely don’t understand the tradeoffs we’re making, though.

@leecow do you know who’s working on Mono macOS packaging who could weigh in? (Or another macOS installer expert?)

/cc @dleeapho