This happens, if the filesystem where dotnet-sdk is installed, is mounted read-only like on NixOS.
To reproduce,
mark AppHostTemplate/apphost as read-only on your dotnet-sdk installation.
chmod -w /nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/sdk/2.2.203/AppHostTemplate/apphost
dotnet tool install -g dotnetsay install the tool
dotnet tool install  -g dotnetsay  
Failed to create shell shim for tool 'dotnetsay': Failed to create tool shim for command 'dotnetsay': Access to the path '/home/bara/.dotnet/tools/dotnetsay' is denied.
Tool 'dotnetsay' failed to install.
Running it with strace, I see that the readonly permissions of the original file are applied, then the file is opened in read-write mode, which fails:
...
openat(AT_FDCWD, "/home/bara/.dotnet/tools/dotnetsay", O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0666) = 114
...
sendfile(114, 113, NULL, 111008)        = 111008
fstat(113, {st_mode=S_IFREG|0555, st_size=111008, ...}) = 0
utimensat(114, NULL, [{tv_sec=1565715605, tv_nsec=506049000} /* 2019-08-13T19:00:05.506049000+0200 */, {tv_sec=1, tv_nsec=0} /* 1970-01-01T01:00:01+0100 */], 0) = 0
fchmod(114, 0555)                       = 0
flock(114, LOCK_UN)                     = 0
close(114)                              = 0
flock(113, LOCK_UN)                     = 0
close(113)                              = 0
openat(AT_FDCWD, "/home/bara/.dotnet/tools/dotnetsay", O_RDWR|O_CLOEXEC) = -1 EACCES (Permission denied)
...
dotnet --info output:
.NET Core SDK (reflecting any global.json):
 Version:   2.2.203
 Commit:    e5bab63eca
Runtime Environment:
 OS Name:     nixos
 OS Version:  19.09pre185176.1036dc66416
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/sdk/2.2.203/
Host (useful for support):
  Version: 2.2.4
  Commit:  f95848e524
.NET Core SDKs installed:
  2.2.203 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/sdk]
.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.2.4 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.2.4 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.2.4 [/nix/store/j44086z2jqw4y5qksvkb7c227dxq3mf1-dotnet-sdk-2.2.203/shared/Microsoft.NETCore.App]
To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
                        cc @wli3
I need to understand more on why NixOS will it mount as read only. And could you tell me how you get the SDK in detail? Like you install it via tar.gz and then mount it or there is a different package manager.
Many components in SDK are permission sensitive, and they have correct permission when using existing official supported method like apt-get, rpm, tar.gz and download script.
Thank you for the reply.
NixOS bases on nix package manager, I am using the dotnet-sdk package, which is based on the tar.gz download.
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/dotnet/sdk/default.nix#L20
Nix strives to make building packages reproducible. It stores packages in /nix/store according to hash of its inputs (hash of dependencies + hash of source files). The files are read-only to prevent user errors and find problems, where installed programs modify their files, which could prevent reproducible builds.
There is a section in the manual for more overview: https://nixos.org/nix/manual/#ch-about-nix
Ensuring, the destination file is writable, after copying, before opening for writing, should fix this issue.
https://github.com/dotnet/cli/blob/v2.2.203/src/Microsoft.DotNet.Cli.Utils/EmbedAppNameInHost.cs#L53
It seams to be fixed in 3.1-preview2
Most helpful comment
Thank you for the reply.
NixOS bases on nix package manager, I am using the
dotnet-sdkpackage, which is based on the tar.gz download.https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/dotnet/sdk/default.nix#L20
Nix strives to make building packages reproducible. It stores packages in
/nix/storeaccording to hash of its inputs (hash of dependencies + hash of source files). The files are read-only to prevent user errors and find problems, where installed programs modify their files, which could prevent reproducible builds.There is a section in the manual for more overview: https://nixos.org/nix/manual/#ch-about-nix
Ensuring, the destination file is writable, after copying, before opening for writing, should fix this issue.
https://github.com/dotnet/cli/blob/v2.2.203/src/Microsoft.DotNet.Cli.Utils/EmbedAppNameInHost.cs#L53