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
Get-Command reports non-executable files (documents) as applications #12625
Comments
It's an odd one. Profile in the example is a command of type "External Script" so that is ok. Foo.xlsx is processable in Excel , and "If I can start it, it counts as an application" might be OK as a rule except that Technically a breaking change because someone might use get-command instead of test-path, but you could make it less so by returning "non-executable" if the input is a path and the path isn't something you can run. |
As @jhoneill said, that's definitely expected with ps1 files. Also even things that aren't directly executable can still be invoked with |
Yes, sorry about the flawed |
Executable loses all meaning if it applies to any file: It is't the file itself that is executable in the case of The most sensible definition of command is: something that is itself executable and to which - at lest in principle - arguments can be passed.
While that may be true on Windows, it isn't on Unix platforms, and that is indeed what prompted creation of this issue (see this Stack Overflow question). Notably, given that executables on Unix-like platforms typically have no filename extension at all, you cannot easily tell whether something is executable or not. The workaround is currently to use Testing an individual file for executability also calls for adding an # WISHFUL THINKING
# On Unix-like platforms: does ./foo have the executable permission bits set
# so that I can execute it?
Test-Path -Executable ./foo However, doing so doesn't preclude also fixing # WISHFUL THINKING
# Get (only) all true executables in the current directory.
Get-Command ./* |
I like the idea of a separate cmdlet or parameter on something else to test executability. I don't think there's anything to fix here though. It's doing exactly what it says on the tin, getting you a command that can be invoked. If the cmdlet was called |
Understood and disagreed. I've given your comment the agreed-on thumbs-down, and conclude this aspect of the debate by reiterating: the current definition of command is meaningless, if any file is a command. Distinguishing between a true executable, and a not-itself-executable document, on which a GUI shell operation can be performed, is useful. Also note that |
It does sort of lose the original spirit if you also provide a counter point though. I don't personally mind it however, I think it makes the conversation easier to navigate at a glance.
A command in this context is a PowerShell concept. It means something that PowerShell can invoke. It doesn't mean an executable file.
Yeah for sure, that'd be a great command.
Yeah I'd be a little bit more comfortable if it was of a |
Fair point: the comment started out as just a succinct reiteration of the original point - so as to clarify the gist of the disagreement - but then the spirit moved me to elaborate. And I'm still possessed:
It is, but it is a concept that is well-established historically, and I don't think that PowerShell in fundamental design intent deviates from it - as evidenced by the command-type enumeration members ( My sense is that if you ask the average PowerShell user: Is Again: The distinction between (a) "a thing that is designed to carry out an action, typically operating on given input (pipeline, arguments)" and (b) "a piece of data stored in a file that can be acted on if passed to an (a)" is an intuitive and useful one. Conversely: If you want the functionality that
To me that illustrates why such files should not be considered commands: essentially, by returning a type of |
The whole thing is a trade off though, you give the other side the final word while still making it clear you disagree. If you want to give a thumbs down and still provide a counter point (or even just a summary), that's still fine obviously (imo), just not related to what we discussed.
Well it's more of an implementation detail. It's processed by the
Yeah sure, it's not a super well known feature.
It's going to act in mostly the same way as a GUI application.
If I'm using
Nope, just a different |
Point taken. I think we agree now that either use of thumbs-down can be useful.
Not only that: As I've just realized, on invocation of a document, it does something that is of questionable utility and likely not what the user intends: see #12632
That will tell you nothing of interest about |
It may not be what you personally expect, but it is by design. I use it every day.
It's not about information, |
I'm genuinely curious: Please give me an example of when you open a document by mere file name (e.g,
Fair point. That still doesn't make something that isn't a command but can be invoked as one a command, and supporting something like |
I don't, I do
Remember that the word "command" has a very specific meaning in the context of PowerShell. What you are asking is for engine to no longer classify all items as commands. While I disagree, that's an understandable perspective to have. That said, your reasoning can't be that it isn't a command, because it already objectively is by design. |
So do I, and I wouldn't want to miss it - and I certainly didn't propose changing that. To be clear: I was talking about invocation by mere file name -
Multiple executables with a given file name in
Indeed that's what I'm asking for, but that doesn't preclude sensible use of syntactic sugar such as That is, if an item turns out to be non-executable - a document - implicitly pass it to the Incidentally, this could be extended to directory paths, so that, say, submitting With this conception:
|
Splitting hairs here, it doesn't say it is an executable. Long ago I was taught programs divided into utilities like format, sort, etc. and applications, word, multiplan, etc. OS programs were all utilities, never applications. And the application data files were a distinct class from configuration data. "App" has come to mean "program" and the distinction has been lost. PowerShell doesn't distinguish application program and application data file It's not a bad assumption that "application" and "executable" are the same thing, but it doesn't hold here. Better naming would help. |
I shortly look the code and it is not a side effect - the code explicitly does this (it seems excluding completor). So I'd said it is "by-design". If there are no security problems, I do not see the need to do the breaking change. |
Something being by design doesn't preclude changing it, if that design turns out to be unhelpful.
The code explicitly does what?
Invoking documents via PS C:\Users\jdoe> WindowsCodecsRaw.txt The above opens Originally I mistakenly thought that a file by the same name in the current directory would take precedence, but that isn't true (I've also updated #12632) - the behavior is consistent in that not using a path (not using, e.g., Still, I don't think it makes sense to locate and open documents this way. In the best-case scenario, it's an unhelpful feature that one won't use, in the worst-case scenario you'll mistakenly operate on the wrong file. Neither does it make sense to report documents as In short: While a breaking change, I think the impact would be minimal (though I haven't try to analyze code out there):
I should have said "command", which is a superset of "executable" (as a noun; as an adjective, it is the core quality of a command). A simple way of conceptualizing the distinction I'm after: a command is a verb ("do something"), a document is a noun ("a thing"). Irrespective of what the original design intent was, observing this distinction is helpful, for the reasons outlined above. The utility (CUI) vs. application (GUI) terminology has always been blurry on Windows, where the term "console application" is common, but I don't think that is relevant here. Application data files are unequivocally what I've called documents above, distinct from the actual application executables, i.e., files containing executable code as recognized by the system. Therefore, from the perspective of the command / document distinction, documents shouldn't be considered commands at all, and |
@mklement0 it seems to me the fundamental distinction here is simply one between your perceived definition of "command" and the one used in the design of the cmdlet. If you're suggesting changes to the command, it's probably more productive to simply illustrate the precise differences you'd suggest and the practical benefits/losses and any breaking changes rather than getting into the semantics; that discussion is practically guaranteed to be unending. The majority of the discussion here doesn't appear to come to any real resolution; the definition of "command" in this context does appear to be a bit looser than some definitions, but as others have pointed out... that is by design currently. |
The OP always contained a concrete proposal, but I've now fleshed it out. Similarly, I hope that the related, but distinct #12632 states its case clearly (and there should be no doubt that #12644 is a bug). The attendant discussion was necessary to make the case for the proposal in the OP, and to suggest a conceptual reframing that I think will ultimately benefit users. Again, that something is by design doesn't preclude changing it - if the impact is small enough, and the benefits are large enough. |
I've spun out the |
Which, in case of a remote session, would be the immortal Norton Commander, I suppose 😛 Returning to indicative mode: when we encounter a number or a string, we do not execute any default action on it, we just emit it to the pipeline. If it ever comes back, the default action will be |
No: An unquoted string triggers argument-mode parsing, where the first argument is interpreted as a command and therefore executed. This already happens for, say, For non-executable files, this is a convenient shortcut to There is no good reason not to offer the same convenience for directory items, so that executing Also, (But keep in mind that all of this still doesn't justify reporting non-executable file-system items as type How a terminal-only remote session should be dealing with such GUI shell operations is a valid question, but we already have that problem; e.g.: # Currently FAILS QUIETLY - ditto with explicit `Invoke-Item c:\windows\system.ini`
icm -cn . { c:\windows\system.ini } I've never considered this case before, but the quiet failure seems problematic. |
When I write string, I mean string. When I write bareword, I mean bareword. And yes, I would prefer this convenient shortcut to cease and desist. |
I see. You should have been talking about barewords then, given that that's what you used in your examples:
Of course, if you truly meant quoted expression-mode strings, then the existing behavior mustn't change: Just to clarify: Are you advocating the removal of the existing ability to use, say, If that is truly what you want, please open a new issue - though I don't ever see such a change happening (nor do I think there's a good reason for it). |
Re-reading your original comment, I think I now see what you meant: However, we have currently have an easy-to-grasp dichotomy:
Leaving the breaking nature of your proposal with respect to bareword file paths aside: What you're proposing - e.g. It also doesn't naturally extend to file-system item paths that require quoting or are expressed via variables. |
I envisage breaking rule #1, in that PowerShell should consider whether the bareword corresponds to a command or not.
There are no file-system paths that require quoting, so I am not sure what you mean by that. |
|
|
Sure, you can work around the problem, but to be forced to do that (not being able to use single- or double-quoting) makes this an awkward solution. Also, it doesn't address variable-based paths; e.g., Aside from the conceptual problems with your proposal, let me restate that I think it has little chance of getting implemented for the reason that it'll break existing bareword non-executable file-path behavior alone. I suggest we stop discussing it here. If you really feel strongly enough to push for a breaking change, please open a new issue. |
Anything you quote becomes a string in PowerShell. In order to have a bareword with funny characters, you need to escape them. Quoting is a work-around for people who find escaping too difficult. |
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
2 similar comments
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes. |
See also: #12632, #12644, #12645
Note: Changing this would be a breaking change. That said, the current behavior is unhelpful, so the suggested change likely falls into Bucket 3: Unlikely Grey Area.
While you can pass a file path to
Get-Command
, any existing file - even if it isn't an executable (let's call it a document) - is currently reported as command of typeApplication
.The sensible behavior would be the following: Only return a file as a
System.Management.Automation.ApplicationInfo
instance:on Unix-like platforms: if
test -x
for that file has an exit code of0
; that is, if the file is an executable from the OS' perspective and is executable by the current user.on Windows: if the file's extension is listed in
$env:PATHEXT
Otherwise, a non-terminating error should be reported, as is already done for non-existent commands.
It isn't useful to end users to report any file item as a command, let alone as a command of type
Application
, as is currently the case (useGet-Item
to get information about non-executable files).Conversely, reporting only true executables (files that the OS considers directly executable) is helpful on Unix-like platforms, given that executables typically have no filename extension at all, and even if they do it isn't the extension that determines executability, it is the permission bits.
In short: It is helpful to distinguish actual executables (from the OS' perspective) from documents that PowerShell - as a syntactic convenience - allows passing to an executable, implicitly (e.g.,
./foo.txt
being the same asInvoke-Item ./foo.txt
). That PowerShell currently allows invoking documents by mere file name (foo.txt
) via$env:PATH
(only), is a related, but separate problem - see #12632.Steps to reproduce
Expected behavior
The test should pass.
Actual behavior
The test fails:
The reason is that the non-executable
t.txt
file was actually reported as typeApplication
.Environment data
The text was updated successfully, but these errors were encountered: