-
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
Argument with colon in it is incorrectly handled if not quoted #23819
Comments
Unfortunately, there are a number of long-standing bugs relating to argument-passing to external (native) programs.
|
In this case the problem isn't with the native parser but just how parameter binding in PowerShell works in general. Calling a native executable command directly will go through one binder that passes through So by the time function Call-ffmpeg {
C:\temp\print_argv.exe $args
}
Call-ffmpeg -i test.mp4 -filter:v null -f null -
"C:\temp\print_argv.exe" -i test.mp4 -filter: v null -f null -
[0] -i
[1] test.mp4
[2] -filter:
[3] v
[4] null
[5] -f
[6] null
[7] -
C:\temp\print_argv.exe -i test.mp4 -filter:v null -f null -
"C:\temp\print_argv.exe" -i test.mp4 -filter:v null -f null -
[0] -i
[1] test.mp4
[2] -filter:v
[3] null
[4] -f
[5] null
[6] - While I can see an argument about this being a bug I personally think it's just how things work and changing the behaviour today would probably result in more problems. The simplest solution here is to just quote your argument or provide it as an array to your wrapper with the value already provided as a string: function Call-ffmpeg {
ffmpeg @args
}
Call-ffmpeg -i test.mp4 '-foo:bar'
Call-ffmpeg @('-i', 'test.mp4', '-foo:bar') |
Ideally there could be something like a
that allows user to change how the "binder" works. |
@jborean93, you're right, the problem is the parameter binder for PowerShell commands in this case. That it is a bug, even by the rules of PowerShell commands, is exemplified by the following:
# !! -> '-foo: bar' - space inserted (due to mistaken interpretation as a parameter name-value pair)
Write-Host -- -foo:bar
# -> !! turns into the equivalent of -foo:$TRUE
& { & { param([switch] $foo) $PSBoundParameters } @args } -foo:$false As for fixing the bug in the context of relaying arguments to native programs - probably the most likely scenario - @BrucePay suggested the following in the aforementioned #6360 (see there for more context):
|
It is perfectly possible to call command like the ffmpeg one you gave from PowerShell . Really the job of an external-command wrapper is to take parameters in PowerShell style (naming each one, allowing them to be in any order if named, suggesting names but removing names when they are not compatible with parameters already provided,
|
@jhoneill I'm so sorry I don't understand what you are talking about. What I asked for is a way to remove this inconsistency as follows:
In Bash, one can just |
You have a valid point but bringing up the age of the tool as if that's the reason why it's not working like Bash is silly. PowerShell aliases are simply different from Bash. I don't like the way Bash handles whitespace but I don't expect them to change it just because other shells do it differently. You can do whatever you want inside a function so just add some additional processing inside your function to join the colon parameters with your value, here's an example to get you started:
|
But why do we have to do this if without the function the "binder" can already correctly process the colons? Why can't there be an option to allow user to use that "binder" for function? I brought up Bash because I think Bash got their priority right. The consistency of syntax with or without function should be the most important to be preserved. PowerShell already has advanced parameter attributes. It should have the colon splatting optional unless a special attribute presents, not the other way:
|
|
OK. Basic premise is that PowerShell commands should all work in the same way. That means they don't have unnamed parameters, and the use of $Args has been discouraged for as long as I can remember. If you write a function to do a bunch of things which use ffmpeg that function should work like everything else in PowerShell , and should take parameters in PowerShell style and translate them when calling ffmpeg.
So far so good, and you can build a function to call that...
Ah, what I hadn't picked up from the first post is that your not doing a bunch of stuff which involves ffmpeg, you just want an alias-with-parameters which PowerShell doesn't naturally do.
This
Is the way many new to PowerShell users who expect their scripts to refer to arguments 1 , 2 and 3 etc would do it writing a PowerShell wrapper for all the parameters to do a simple fix like this is horribly laborious - but when it it is fixing a particularly awkward utility PowerShell's assumptions about prepping stuff for a PowerShell command mean the roof falls in.
Yup. PowerShell aliases were to replace names. Re-writing the command and all its parameters, use
Like so many other things if you know where to look PowerShell had a solution back at the start. |
Thank you! |
While it's always good to know a workaround, we shouldn't lose sight of the bigger picture:
The - obscure - Here's a simple example (run on Windows): function foo { iex ($MyInvocation.Statement -replace '^foo\b', 'cmd /c echo') }
$i = 0; foo (++$i) This prints (It also doesn't address automatic support for pipeline input, though you can't fault it for that, as even fixing the bug at hand wouldn't address that; only #12962 (comment) would.) |
Prerequisites
Steps to reproduce
I understand the
-<arg_name>:<arg_value>
syntax in PowerShell. But it seems there lacks a way to tell PowerShell to simply passing the argument as-is without parsing, without requiring caller to explicitly quoting the whole thing. I found the issue #6292 (comment) discussed this 6 years ago, but I can't find any fix for that issue. If I'm missing a solution to this, please let me know.Why does this matter? Because some applications like ffmpeg extensively use the
-<arg_name>:<arg_value>
syntax. There is no way to write a function to wrap such application cleanly.Expected behavior
Actual behavior
Error details
No response
Environment data
Visuals
No response
The text was updated successfully, but these errors were encountered: