简体   繁体   English

Powershell 调用 cmd.exe 命令,如 copy /b

[英]Powershell call cmd.exe command like copy /b

I saw this already Fast and simple binary concatenate files in Powershell我已经在 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 :当我调用cmd.exe命令时,例如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我得到一个错误Copy-Item: A positional parameter cannot be found

As the error alludes to, copy is actually just an alias for Copy-Item and it does not have a /b parameter.正如错误所暗示的那样, copy实际上只是Copy-Item的别名,它没有/b参数。 You can call cmd to use its copy command.您可以拨打cmd使用其复制命令。

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

Note: This answer complements Doug Maurer's helpful answer , which provides an effective solution (for file names without spaces).注意:此答案补充了Doug Maurer 的有用答案,它提供了一个有效的解决方案(对于没有空格的文件名)。

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): PowerShell 如何解析未加引号的复合标记,例如$($args[0])+$($args[1]) (复合标记是指直接连接的不同语法结构)有一个微妙之处:

$($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: $($args[0])+$($args[1])结果是两个arguments [1] - 尽管使用手头的特定命令( cmd.exe的内部copy命令)恰好不是问题:

  • Argument 1: The value of $($args[0])参数 1: $($args[0])的值

  • Argument 2: A verbatim + directly followed by the value of $($args[1])参数 2:逐字+直接跟在$($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 ;但是,如果$args[0]$($args[1])包含空格copy命令将出现故障 it is therefore more robust to pass the file names and the + as separate arguments , which copy also supports:因此,将文件名和+作为单独的 arguments 传递更加可靠,该copy还支持:

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]) [1] 您可以按如下方式验证: $arr='foo', 'bar'; cmd /c echo $($arr[0])+$($arr[1]) $arr='foo', 'bar'; cmd /c echo $($arr[0])+$($arr[1]) , which yields: foo +bar (note the space). $arr='foo', 'bar'; cmd /c echo $($arr[0])+$($arr[1]) ,它产生: foo +bar (注意空格)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM