PowerShell doesn't start if env var HOME is not defined#3437
PowerShell doesn't start if env var HOME is not defined#3437lzybkr merged 1 commit intoPowerShell:masterfrom
Conversation
|
We can use Path.GetTempPath |
|
I'll update it to use |
There was a problem hiding this comment.
Does this need to be public?
And shouldn't it return the same directory every time it's called?
There was a problem hiding this comment.
making it internal. yeah, it should return the same directory per process
There was a problem hiding this comment.
It doesn't really matter here because the loop should only run once, but as a matter of style, you should move calls that always (or should always) return the same thing (like Path.GetTempPath) outside of the loop.
There was a problem hiding this comment.
There is still a race here - extremely unlikely, but another thread/process could create the same directory you're trying to create.
There was a problem hiding this comment.
CreateDirectory will return tempDir if that directory already exists
There was a problem hiding this comment.
Should we protect Windows too?
There was a problem hiding this comment.
Looking at the code where "USERPROFILE" env var is used, it appears to handle the case where it's null already
There was a problem hiding this comment.
I open Issue to enhance New-TemporaryFile cmdlet to return a temporary directory.
So maybe we move the code to PSUtils.cs?
There was a problem hiding this comment.
Infinite loop can happen.
There was a problem hiding this comment.
not sure how we can be in an infinite loop realistically here
There was a problem hiding this comment.
In the worst case, here we can get UnauthorizedAccessException.
There was a problem hiding this comment.
Will wrap in try..catch
There was a problem hiding this comment.
I believe the comment not clear enough (unique for current process?).
There was a problem hiding this comment.
Maybe remove the cycle? If we believe that it cannot be infinite that means we believe that NewGuid is always globally unique and then the cycle is generally not needed.
There was a problem hiding this comment.
It seems like the risk of an infinite loop is slightly lower than the risk of NewGuid() not being unique although realistically, I expect both to be practically not a real issue but having the loop seems very slightly safer.
There was a problem hiding this comment.
Oh, sorry, I again don't understand the comment for the first time. Could you make it more clear?
There was a problem hiding this comment.
Assuming this scenario is common (no HOME), we'll eventually create a ton of these directories.
I think we should either:
- Use a reproducible name
- Remove the directory before the process exits
There was a problem hiding this comment.
Don't know how common this will be, but cleaning up makes sense. Putting it in ConsoleHost.Dispose()?
There was a problem hiding this comment.
If this is a common scenario, then perhaps we should require to specify a temporary directory using one of the possible ways?
There was a problem hiding this comment.
@iSazonov although not discoverable, for advanced uses you can define XDG_CONFIG_HOME, XDG_CACHE_HOME, and XDG_DATA_HOME env vars which PowerShell will use (on non-Windows). This was really only to support simple cases (like Puppet) to not put a barrier for adoption of PowerShell
There was a problem hiding this comment.
I meant that maybe we need to specify in the documentation that for proper PowerShell operation, users need to define (enumeration here) variables.
There was a problem hiding this comment.
Created doc bug MicrosoftDocs/PowerShell-Docs#1126
I don't think users should be required to create those env vars, we should just work in most cases
There was a problem hiding this comment.
should it really be "public"?
There was a problem hiding this comment.
I was thinking it would be useful for cmdlet authors rather than having to rely on HOME for Unix and USERPROFILE for Windows
There was a problem hiding this comment.
Actually, perhaps we should keep it internal for now until https://github.com/PowerShell/PowerShell-RFC/blob/master/1-Draft/RFC0019-PowerShell-Core-Interop-Module.md gets resolved
There was a problem hiding this comment.
It's just a constant - makes no sense.
We would discuss this in the topic about creating platform unified scripts to get common solution and best practices. But we have not yet created such a discussion.
There was a problem hiding this comment.
I meant that maybe we need to specify in the documentation that for proper PowerShell operation, users need to define (enumeration here) variables.
|
LGTM. |
|
@iSazonov can you mark your review as |
|
Approved. |
lzybkr
left a comment
There was a problem hiding this comment.
Looks good except there is no cleanup.
We don't really have an ideal place for engine wide cleanup. ConsoleHost.Dispose isn't it - that only applies to the console host.
One possibility is when closing the last runspace (LocalRunspace.Dispose or something like that.) This is somewhat clean because we track all of the runspaces for debugging, but it does require extra care because a host may create new runspaces after you've deleted the directory.
|
@lzybkr clean up added |
|
I'd not worried much about cleaning up temporary files and directories because the implication is that it's "trash", which can be removed by the user or by the system at any time. For example, Windows has Disk CleanUp Utility (I run it regularly on users computer by SCCM, GPO and scheduled tasks) and a group policy to create a temporary directory on the user session (%temp% is created on logon and removed on logoff). |
|
Cleanup is important because shell processes are sometimes created frequently, and degrading system performance due to too many directories in TMP is not something we want to do. Not everybody cleans up TMP, or maybe not often enough at any rate. |
|
@SteveL-MSFT - I've approved the code, but would you mind squashing and improving the commit message? |
|
@lzybkr I'll take care of it next week, at Whistler this week without my laptop |
used does not have a home directory. Updated PowerShell to use a process specific temporary directory if HOME, CONFIG, CACHE, and DATA directories are not availble. Temporary directory is cleaned up when last runspace is disposed.

In some environments (like Puppet), the HOME env var is not defined and this causes PowerShell to fail to start as it assumes HOME is available and tries to end up concatenating $null with a string. Fix is to return an empty string instead of $null. Side effect is that some working directories like
.cacheget created in the current working directory instead of HOME (which doesn't exist in this case) which seems acceptable.Addresses #1794