Powershell call cmd.exe command like copy /b

与世无争的帅哥 提交于 2021-01-04 02:06:35

问题


I saw this already Fast and simple binary concatenate files in Powershell

I'm not interested by the answer above I'm interested about what's wrong with syntax below :

when I call a cmd.exe command like copy /b:

function join-file {
   copy /b $($args[0])+$($args[1]) $($args[2])
}

I get an error Copy-Item : A positional parameter cannot be found


回答1:


As the error alludes to, copy is actually just an alias for Copy-Item and it does not have a /b parameter. You can call cmd to use its copy command.

function join-file {
   cmd /c copy /b $($args[0])+$($args[1]) $($args[2])
}



回答2:


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:

  • Argument 1: The value of $($args[0])

  • Argument 2: A verbatim + directly followed by the value of $($args[1])

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).



来源:https://stackoverflow.com/questions/64827770/powershell-call-cmd-exe-command-like-copy-b

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!