Note: This answer complements Doug Maurer's helpful answer, which provides an effective solution (for file names without spaces).
There's a subtlety in how PowerShell parses unquoted compound tokens such as $($args[0])+$($args[1])
(by compound token I mean directly concatenated distinct syntax constructs):
$($args[0])+$($args[1])
results in two arguments[1] - although with the specific command at hand (cmd.exe
's internal copy
command) that happens not to be a problem:
To avoid this problem, enclose the whole compound token in "..."
, so as to predictably treat it as an expandable string.
The upshot:
To be safe, use double-quoting ("..."
) explicitly to enclose compound tokens that involve variable references or subexpressions.
By contrast, to reference a variable or even method call in isolation, neither quoting nor enclosing in $(...)
, the subexpression operator, are needed.
Applied naively to your command (see the better solution below):
# Note: See better solution below.
function join-file {
# Note the "..." around the first argument, and the absence of quoting
# and $(...) around the second.
cmd /c copy /b "$($args[0])+$($args[1])" $args[2]
}
However, if $args[0]
or $($args[1])
contained spaces, the copy
command would malfunction; it is therefore more robust to pass the file names and the +
as separate arguments, which copy
also supports:
function join-file {
# Pass the arguments individually, which obviates the need for quoting
# and $(...) altogether:
cmd /c copy /b $args[0] + $args[1] $args[2]
}
[1] You can verify this as follows: $arr='foo', 'bar'; cmd /c echo $($arr[0])+$($arr[1])
, which yields: foo +bar
(note the space).