-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
While not common, it is possible to use hashtable-based splatting for passing arguments to external programs.
Unfortunately, PowerShell chooses to represent a parameter-name-argument pair as a single token with : as the separator.
E.g., using hashtable $ht = @{ foo = 'bar' } for splatting (as @ht) produces single argument
-foo:bar.
To my knowledge it is uncommon for external CLIs to support this syntax.
By far the most common syntax is to separate the parameter name from its value with a space (effectively passing the parameter value as a separate argument: -foo bar, as is typically used even in PowerShell itself.
Note that Boolean entries in the hashtable would need special consideration: under the sensible assumption that they represent the equivalent of switch parameters in PowerShell, i..e, to options in POSIX parlance (e.g., grep's -o option) :
-
a value of
$truewould have to result in the key name by itself; i.e., an entry ofo = $truewould result in-o -
a value of
$falsewould have to result in the omission of the entry.
Technically, this would be a breaking change.
If not an option, it is a candidate for #6745.
Note that per POSIX only single-character parameter names are allowed; while the GNU utilities on Linux distros do support multi-character names, they require -- rather than - as the sigil (e.g., --only-matching as the alias of -o with grep); therefore, use of the long option names wouldn't work with the above proposal.
Steps to reproduce
Run the following Pester test on macOS or Linux (the behavior would be the same on Windows, but bash is used to echo the arguments passed).
Describe "Hash-table based splatting with external programs" {
It "Parameter names and their arguments should be separated with spaces" -Skip:$IsWindows {
$htArgs = @{
foo = 'bar'
}
bash -c 'echo \"$@\"' - @htArgs | Should -Be '-foo bar'
}
}Expected behavior
If spaces were used, the test would pass.
Actual behavior
The test fails:
Expected: '-foo bar'
But was: '-foo:bar'
Environment data
PowerShell Core 6.2.0