Powershell“调用”传递重定向到程序而不是执行它

问题描述 投票:0回答:2

我正在尝试让 powershell 调用带有构造参数列表的 exe - 并将响应通过管道传输到日志文件。 我的问题是重定向字符似乎传递给了 exe。 (我也挣扎了将近一天才在充满空格的路径名周围找到正确的引号!!!)

exe 的语法是

   filemeta  {-d|-i|-e} [-c] [-f=<directory name>] [-x=<file name>] [-v]
             [-p] [--] [--version] [-h] <file name> ...

正如你所看到的重复。我认为重定向作为另一个文件名传递的原因首先是错误消息 找不到文件“>>” 其次,日志文件未填充

粘贴到命令提示符中的以下命令执行预期的操作。它只是如何将它包装在 powershell 文件迭代中

"C:\Program Files\File Metadata\FileMeta.exe" -i -f="M:\metadata_XML_tobe\ManagedCatalog\Business Records\Morse Bakery"  "M:\ManagedCatalog\Business Records\Morse Bakery\Morse Bakery Book 1-000.JPG"  >>"M:\metadata_XML_tobe\apply_doc_id_20230412-124532.log" 2>>&1 

到目前为止的 powershell 命令是 ...

$metaDataPath = 'M:\metadata_XML_tobe'
$timeStr = get-date -Format 'yyyyMMdd-HHmmss' 
$logFileName = $metaDataPath + "\apply_doc_id_" + $timeStr + ".log"
$files = Get-ChildItem -Path $metaDataPath -Recurse -Include *.xml
$quote = '"'
$hits  = 0
foreach ($f in $files){
    $hits++
    if ($hits -ge 5) {
        break
    }
    $directory = [System.IO.Path]::GetDirectoryName($f)
    $realFile_name = $f.FullName.Replace('.metadata.xml', '')
    $realFile_name = $realFile_name.Replace('\metadata_XML_tobe', '' )
    $parm1 = '-i'  
    $parm2 = '-f='+ $quote + $directory + $quote 
    $parm3 = $quote + $realFile_name + $quote
    $parm4 = ' >>'  
    $parm5 = $quote + $logFileName + $quote
    $parm6 = ' 2>>&1'  
    Write-Host '**************'
    Write-Host $f.FullName 
    Write-Host  '   Parm1   = ' $parm1
    Write-Host  '   Parm2   = ' $parm2
    Write-Host  '   Parm3   = ' $parm3
    Write-Host  '   Parm4   = ' $parm4
    Write-Host  '   Parm5   = ' $parm5
    Write-Host  '   Parm6   = ' $parm6
    echoargs 'C:\Program Files\File Metadata\FileMeta.exe' $parm1 $parm2 $parm3 $parm4 $parm5 $parm6
    # & 'C:\Program Files\File Metadata\FileMeta.exe' $parm1 $parm2 $parm3 $parm4 $parm5 $parm6
}

输出 -----

M:\metadata_XML_tobe\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG.metadata.xml
   Parm1   =  -i
   Parm2   =  -f="M:\metadata_XML_tobe\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948"
   Parm3   =  "M:\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG"
   Parm4   =   >>
   Parm5   =  "M:\metadata_XML_tobe\apply_doc_id_20230417-105352.log"
   Parm6   =   2>>&1
Arg 0 is <C:\Program Files\File Metadata\FileMeta.exe>
Arg 1 is <-i>
Arg 2 is <-f=M:\metadata_XML_tobe\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948>
Arg 3 is <M:\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG>
Arg 4 is < >>>
Arg 5 is <M:\metadata_XML_tobe\apply_doc_id_20230417-105352.log>
Arg 6 is < 2>>&1>

或者如果 echoargs 被换掉了

**************
M:\metadata_XML_tobe\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG.metadata.xml
   Parm1   =  -i
   Parm2   =  -f="M:\metadata_XML_tobe\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948"
   Parm3   =  "M:\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG"
   Parm4   =   >>
   Parm5   =  "M:\metadata_XML_tobe\apply_doc_id_20230417-105958.log"
   Parm6   =   2>>&1
Imported metadata to M:\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG from M:\metadata_XML_tobe\ManagedCatalog\Church Records\Catholic Church Euroa\Baptism Records\1904-1948\Baptism Records 1904-1948-003.JPG.metadata.xml
Cannot find file " >>"

请帮我理解这个迷宫

JC

powershell quotes io-redirection
2个回答
0
投票

与在任何 shell 中一样,元字符(例如

>
未使用 literally,unquoted 不会被这样处理:

# OK: > $null redirects the success-stream output to $null, i.e. 
#     *discards* it:
# NO OUTPUT, as expected.
Write-Output hi > $null

# !! Due to saving *string* value '> $null' in a variable
# !! and passing that variable, its *verbatim value* is passed.
# OUTPUTS 'hi' and '> $null'
$var = '> $null'
Write-Output hi $var

也就是说,使用 variables 为给定的目标可执行文件指定 pass-through arguments 与尝试传递 shell 重定向 根本不同,例如

>>
- 只有前者通过按原样引用变量来工作在命令行上。


如果您确实需要通过 variables 指定 redirections,您可以使用

Invoke-Expression
,这是 通常要避免的,但是:

# Define the command to invoke with all its arguments, but without redirections,
# as a script block ({ ... }), to be invoked later.
$scriptBlock = { Write-Output hi }

# Define the desired redirection as a variable.
$redirection = '> $null'

# This is now the equivalent of:
#   Write-Output hi > $null
Invoke-Expression "& $scriptBlock $redirection"

0
投票

谢谢 mklement0 (这不是答案,但评论太长了 - 抱歉) 我想我理解你所说的重定向符号;如果它们实际上不存在,那么它们将被视为变量。 我似乎以这种方式结束,因为如果不先将它们连接在一起,我就无法形成 '-f=directory' 因此,如果我必须将其放入变量中,那么为什么不将“-i”和“>>”也放入变量中。然后他们都一样处理。 但是你能帮我理解其他一些差异吗 从所有这些试验中我得出了一些“规则”,如果你能证实或纠正我的理解,那将对我很有帮助 注意:我假设任何路径的名称中都可以包含空格

     & "C:\Program Files\File Metadata\FileMeta.exe" -i $parm2 $parm3  *>> $logFileName
     & "C:\Program Files\File Metadata\FileMeta.exe" -i $parm2 $parm3  *>> $logFileName
     | _____________________________________________ ----------------- ___ -----------------
     1              2                                       3           4        5
1 = The command or verb
2 = what to call. Can use single or double quotes
3 = anything up to pipe or redirect characters. MUST use DOUBLE quotes around paths
    even though these are stripped out. If you use single quotes you get an error like <Cannot find directory for arg Argument: f>
4 = Pipe or redirect chracters. Must be in the clear (not part of a variable)
5 = file names etc after the redirects.  MUST NOT use either double or single quotes - even if there are spaces in the path

然后还有其他混淆 - 来自不同帖子的想法在这里不起作用。例如

$日志文件名 2>>&1 “重定向运算符后缺少文件规范。” 但是 *>> $logFileName 确实有效。

难怪我很困惑。这东西不是同质的,所以我真的不知道什么时候使用哪一套规则。 感谢期待 杰西

© www.soinside.com 2019 - 2024. All rights reserved.