New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a platform-agnostic way to determine the temp. directory, e.g., via an automatic variable. #4216
Comments
what about something like: (New-TemporaryFile).DirectoryName |
@lukeb1961: That indeed yields the platform-specific temporary directory, but it has an unwanted side effect: In other words: every time you execute Additionally, it's a computationally expensive approach. |
We've had discussed this in a nutshell. Thank you for opening the Issue. Internally we already have "TemporaryDirectory", just "GetTemporaryDirectory()" and "CreateTemporaryDirectory()". We could make it public. |
How about going with $Env:TMP on all platforms? That is not quite like Windows, Mac, or Linux. No turf war. |
@Liturgist: An automatic PowerShell variable such as |
If we went the variable route, it would have to be something like $interop:TEMP to avoid name collision. A variable is probably easier to use in scripts than an API although we can certainly support both. In #3571 I suggested other variables in addition to TEMP |
Good point; an If we take a step back: If we want PowerShell to become the lingua franca of the shell world, do we really want to frame things as "interop"? How about trusting PowerShell's automatic variables to Do the Right Thing(TM) generically, which would call for a namespace such as |
@mklement0 the Personally, I prefer cc @PowerShell/powershell-committee |
I'm glad to hear it, @SteveL-MSFT. On a related note, I think a separate namespace for all preference variables would be beneficial as well, such as The caveat is that even though collisions are far less likely than with unqualified variable names, someone could have done something like the following: # Define custom drive 'ps:'
New-PSDrive 'ps' FileSystem '/tmp'; Get-ChildItem ps: |
That works, but it is both hard to remember and cumbersome to type. |
If we have |
Since the term path is ambiguous (even though it is used in the .NET API to refer to a directory path in this case), my preference would be That said, a cmdlet is a bit heavy-handed for something that returns a single piece of information with no variations in functionality. Consider the existing |
|
We would make |
I would prefer a consistent way of mapping environment variables that are basically the same just expressed differently. Are we saying we will map all path variables to drives, like Home:? |
@mklement0 - I am not quite sure why |
@Liturgist I think the notion is that anything in the The proposals for a separate namespace or drive eliminate that issue as it allows for PowerShell to have it's own commonly defined variables that can be used cross-platform and not block access to the real environment variables. Another idea though for a namespace could be |
@dragonwolf83 - Would To go with |
No, I don't think the PowerShell team would move
In other words, it exists exactly where it belongs. Take a look at the screenshot below. It shows the Environment Variables defined on my Windows system. It has TEMP and TMP as environment variables for my user Temp path. It also has PSModulePath. So all of those other variables, I would expect to see in |
To add to @dragonwolf83's helpful comments and to respond to your comment addressed to me:
My perhaps glaringly-obvious-didn't-need-to-be-said point was that in the absence of PowerShell actually defining such an environment variable (which, as stated, would be ill-advised - also see below), PowerShell shouldn't pretend that it exists. PowerShell respects / defines only two environment variables, according to
These variables are environment variables for a good reason: they allow you to control PowerShell's startup behavior externally. By contrast, there is NO good reason to define the directory for temporary files and directories as an environment variable:
If a reader is familiar primarily with I definitely like the idea of multiple namespaces for PowerShell's automatic variables (such as the suggested |
Seems like there's been enough good discussion that perhaps this should be a RFC? |
In [io.path]::GetTempPath() the [io.path] is a namespace - should we introduce a Powershell "native" namespaces like |
Before we tackle an RFC, let me try to summarize what I perceive to be the use cases and perhaps get a better understanding of the scope of such an RFC:
As for the introduction of PowerShell-controlled namespaces: Note that the current namespace notation - e.g., If we now introduce namespaces such as So what should an RFC cover?
I could tackle the former, but I'm not sure I can come up with a sensible approach to the latter (and it may not be worth doing). |
@mklement0 thanks for summarizing all the different related discussions. I think just scoping the |
@mklement0 - Very nice and helpful summary. I would much rather have |
Thank you, @Liturgist. I hear you re On the opposite end of the spectrum, you could argue (as someone already has, but I forget where) that there should be just one generic Either way, I suggest you make your voice heard at #3442. @SteveL-MSFT: Thank you for the guidance, but despite my initial willingness to tackle this RFC, I'd like to bow out of this [self-]assignment. |
Requiring an admin-scripter to use [IO.Path]::GetTempPath() is obscene. It's not discoverable, it's not obvious, and it's not powershell. I personally believe that promoting $env:tmp is the right answer, but someone could argue it's also not powershell. After some personal consideration, I think a new cmdlet Get-TemporaryDirectory (or a similar name) is the proper answer. I don't understand "New-TempDirectory". The normal use-case is not creating a directory (which New-* indicates) - it's retrieving the name of an existing directory (which Get-* indicates). I'm "meh" about a temp: drive because, for it to be discoverable, it also requires one or more cmdlets. Instead of offering more "freedom" to the scripter, a temp: drive feels constraining. |
Another look to be completely PowerShell native. Can we avoid the explicit use of temporary directories? # Create the file in temporary directory
$temp= New-Item -Path xyz.txt -Temporary
# Get the file and copy it to temporary directory
$var2 = Get-Item -Path sample.txt; $tempVar2 = Copy-Item $var2 -Temporary
# The temporary directory is automatically created and dropped for the scope |
I feel it should simply abstract away the existing platform with the longest standing powershell platform's references being preferred so that the long standing code can be more easily reused. Like this:
|
Looking back at the subject of this thread, some may want to get what might be considered the traditional "tmp" directory. This could return [System.IO.Path]::GetTempPath(). This would obviate the need for a new namespace or provider (ps:, PSEnv:, etc.).
If a developer wants to use $Env:TEMP, or $Env:TMPDIR, or /tmp then they are free to do that. They would be making their code platform dependent. Applications need mechanism to create unique directories and files in which to store things. What if we extended New-Item to be able to create one or more temporary directories and files. It would return a list of the item names. The item names returned will already be created and ready for use.
|
Just to summarize the discussion so far: We're talking about two complementary use cases here, although one is far more important:
|
@mklement0 Thanks for the great summarization! I think we could continue considering scenarios in which all these options could be useful (like "get a file from web/network, put in temp, process the file (unpack/decoding...), remove the temp"). I think we can do more wonderful things than just return temp directory. |
I hit this recently while playing with Azure Functions. I'm so used to having |
Based on above discussion the simple mapping to Temp: drive looks not so useful and not resolve common scenarios. (Users can implement this with one command in profile. In Azure it is possible simply cd to temp.) |
At that level it's not especially useful, @iSazonov, but the change is helpful to future module authors, who could simply refer to |
@SteveL-MSFT - maybe this issue should be renamed and re-scoped to "implementation-agnostic" to cover things like cloud shells without implying they are a platform in the same way an OS is. The name change helps reflect the broader value proposition when bringing serverless / non-OS implementions into scope. |
Thank you for curating the issues, Michael Klement. It seems that the tradition of a tmp/temp directory is that every program can us it in whatever way it wants. That works until name collision or there are multiple instances of the same program. In the first case, the applications must choose different names. In the second, the application may identify its files by including unique information such as its PID in the filename. (a) I fully agree that with guaranteed uniqueness, the application should not care about where a temporary file or directory is located or the name. A constraint should be that it is possible to locate post-mortem the temporary files and directories to enable anomaly remediation (finding and fixing bugs). Does this suggest that automatic temp cleanup should be a preference setting? The suggestion of -NamePrefix was based on an application being able to identify its own temprrary files in a single pool. Although guaranteed uniqueness obviates this as a requirement, the developer may find comfort in recognizing foo_xxxx.tmp, bar_xxxx.tmp, bosh_xxxx.tmp, and others when mutiple temporary files are in use. I agree that if we have New-TemporaryFile that we should have New-TemporaryDirectory. |
Certainly |
What was the result of this discussion? |
A |
@SteveL-MSFT - Ok. I do not see a Will the Will there be a |
@Liturgist It was an experimental feature. Now it is in 7.0. You can download daily build and find it there. It is "global" in PowerShell session. |
@Liturgist if you want to try it on 6.2.1, just do this: Enable-ExperimentalFeature PSTempDrive Then restart pwsh. |
🎉This issue was addressed in #9872, which has now been successfully released as Handy links: |
I'm trying [System.IO.Compression.ZipFile]::ExtractToDirectory($path, "TEMP:\foo") or unzip foo -d TEMP:\foo I must use |
You must translate PS-drive-based paths to their underlying "native" filesystem paths, which is what Note that there's another pitfall associated with passing filesystem paths to .NET methods (though not to external programs): .NET typically sees a different working directory than PowerShell, so that passing relative paths typically doesn't work as intended - it is best to pass full paths always, which In short: it's good to form a habit of passing filesystem paths to .NET methods via If you stay in the realm of PowerShell, you won't face that problem; for instance, you could use |
Related: #3442 and #4215
The various supported platforms have different native ways to determine the directory in which to store temporary files and directories:
$env:TEMP
$env:TMPDIR
/tmp
Currently, there is no platform-agnostic way to refer to this directory, which is cumbersome.
An automatic variable, say
$TEMP
, could provide this abstraction.Environment data
The text was updated successfully, but these errors were encountered: