-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Inconsistent, unpredictable behavior of "-"-prefixed barewords in argument mode #4624
Comments
As a point of clarity, this is not something under PowerShell's control as the calling shell (bash, another PowerShell, CMD, ksh, etc) has final say in the matter. What you are specifically requesting here is to maintain the current argument parsing for arguments passed from the calling shell to the PowerShell binary upon initialization. Correct? |
Correct: Calling from a POSIX-like shell (Unix; e.g., Conceivably, PowerShell could - but shouldn't, in my view - then place additional requirements on the arguments passed, based on its syntax requirement, such as for the received If such a requirement existed, you'd have to call Unfortunately, we already have that awkwardness with respect to how # Oops! "The string is missing the terminator: '."
# PowerShell ended up interpreting `Write-Output don't` as the script.
powershell -noprofile -command Write-Output "don't"
# OK, but clearly cumbersome:
# With shell-variable-based arguments, it gets even trickier.
powershell -noprofile -command Write-Output "\"don't\"" See #4024 (comment) for more. |
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. |
1 similar comment
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. |
Follow-up to #4576 and #4591
Context:
Note: By bareword I mean a run of non-whitespace characters not single- or double-quoted as a whole (e.g.,
foo
), used in argument mode, and normally interpreted as an expandable string (e.g.,$HOME/boy
).While
-
-prefixed barewords look like parameter names (e.g.,-foo
), they sometimes act as arguments (values to bind to parameters), and the ability to use them as such is important in two contexts:In the context of the external CLI, when passing the name of a script file that happens to start with
-
; e.g.,powershell -File -foo.ps1
When passing arguments through that themselves happen to be command line or command-line fragments, which is enabled by cmdlets/advanced functions that declare a
ValueFromRemainingArguments
parameter; e.g.,Get-Command -Syntax Get-ChildItem -Path cert:
passes-Path cert:
through (the-Path
bareword is not interpreted asGet-Command
's parameter) in order to discover the certificate provider's dynamic parameters.Note that, except when using the external CLI, you can always use quoting to explicitly mark a bareword as an argument.
Generally, though, if there's no ambiguity, not having to quote tokens that don't strictly need it is a matter of convenience.
The problem:
There are two major problems with how
-
-prefixed barewords are currently parsed and interpreted:Pragmatically speaking, their syntactic role (parameter name vs. argument) is virtually unpredictable by the end user.
-a
inGet-Item -LiteralPath -a
is an argument, whereas the-c
inGet-Item -LiteralPath -c
is parameter name-Credential
.They are not parsed and expanded in the same way as barewords that do not start with
-
.a$HOME
expands$HOME
, while-a$HOME
does not.More examples below.
Solution options:
Leave things as they are and document the current behavior, recommending that quoting be used for predictability.
Change the parameter binding as proposed in Parameter values disambiguated with their explicit parameter names should not require quoting #4576: Once a parameter has been (unambiguously) identified, its specific definition - switch vs. parameter-with-argument- alone determines whether the next token is its argument or a different parameter:
E.g., in
Get-Item -LiteralPath -p
,-p
would unambiguously be an argument, because-LiteralPath
syntactically requires an argument.An argument can be made that in cases where the user intent was likely different - e.g.,
Get-Item -LiteralPath -Path
- that unconditional interpretation of-
-prefixed barewords as parameter names is preferable in terms of the user experience (Missing an argument for parameter 'LiteralPath'
as opposed toCannot find path '-Path' because it does not exist
); a point that @markekraus has made.That said, I think the conceptual simplicity and clarity of the let-the-identified-parameter-determine-the-next-token's-syntactic-role approach is more beneficial in the grand scheme of things.
Note: @lzybkr has already discounted this option based on implementation cost, but I'm resubmitting it for consideration now that we have a fuller picture of all the issues involved:
Disallow
-
-prefixed barewords altogether, as proposed in "-"-prefixed barewords in argument mode should always be interpreted as parameter names #4591: In order for a-
-prefixed tokens to be recognized as an argument, it would have to be single- or double-quoted .E.g.,
Get-Item -LiteralPath -a
would then break, becauseGet-Item
has no-a*
parameter, andGet-Item -LiteralPath '-a'
would have to used consistently. (But, in contrast, PowerShell's outside CLI would still need to accept something like-File -a
.)The convenience of being able to specify
-
-prefixed tokens as arguments is lost, but at least the behavior is predictable.ValueFromRemainingArguments
parameter, where, based on the current behavior, a-
-prefixed barewords if it happens not to match a regular parameter would still be interpreted as an argument.Examples:
Environment data
The text was updated successfully, but these errors were encountered: