从powershell函数内部输出来自外部命令的输出

时间:2012-11-23 20:51:07

标签: powershell powershell-v3.0

请考虑以下命令:

7z.exe a -t7z folder.7z folder

我有以下两个精简版PowerShell脚本

文件1:common.ps1

function Archive-Folder ($src, $dest_path, $archive_name) {

    $script_dir = split-path $script:MyInvocation.MyCommand.Path

    if ((test-path $src) -eq $false) {
        write-error "$src is not a valid source directory"
        #return
        return $false
    }

    if ((test-path $dest_path) -eq $false) {
        write-error "$dest_path is not a valid destination directory"
        #return
        return $false
    }

    if ([string]::IsNullOrWhiteSpace($archive_name) -eq $true) {
        write-error "$archive_name is not a valid archive name"
        #return
        return $false
    }

    write-verbose "archiving the folder"

    $archive_command = "$script_dir\7z.exe a -t7z $dest_path\$archive_name $src"

    $exe = "$script_dir\7z.exe"
    $arguments = @('a', '-t7z', "$dest_path\$archive_name", "$src")

    iex $archive_command

    # this doesn't stream the output. it prints it all at once.
    # & $exe $arguments | write-verbose

    return $true
}

文件2:script.ps1

$script_dir = split-path $script:MyInvocation.MyCommand.Path
. "$script_dir\common.ps1"

$VerbosePreference = "Continue"

$src = 'C:\some\source'
$backup_path = 'C:\some\destination'
$date_format = 'yyyy_MM_dd_HHmm'
$date = get-date
$date_str = $date.tostring($date_format)
$date_ticks = $date.ticks
$archive_name = "backup-$date_str-$date_ticks.7z"

# this prints the output streamed. The output ends with `True`
archive-folder $src $backup_path $archive_name 

# the following however doesn't output anything. in order to separate the command output from my function output, 
# i was printing the command output using write-verbose
$isSuccess = archive-folder $src $backup_path $archive_name
if ($isSuccess -eq $true) {
    #proceed with the rest of the code
}

来自@Christian& @zdan,我能够将问题与捕获返回值隔离开来。与archive-folder类似,我有其他函数执行一些命令行工具。我认为这些函数中的每一个都可以返回true或false,具体取决于是否使用正确的操作调用了函数,并且命令行工具是否正确执行。

但是,如果我捕获了archive-folder函数的返回值,则命令的输出不会打印到控制台。此外,我的返回值不包含true或false值。它由命令的整个输出组成。

我第一次尝试解决此问题的方法是将命令执行语句写为iex $archive_command | write-verbose,但这不会输出输出。

我想我可以检查命令行工具在成功的情况下(如存档文件的存在)的副作用,以确定我的功能是否成功执行,但我不确定是否能够为所有功能执行此操作我最终可能会创作。

有没有办法返回一个值并流式化命令行工具的输出?

编辑2

关于为什么我将代码分成两个单独的文件/函数,我的实际使用场景如下

  

script.ps1将协调此流程。备份数据库(mongodb为每个db集合生成文件)。归档数据库备份。将存档上传到S3。这些步骤中的每一步都将由common.ps1中的单独功能完成。 script.ps1只包含胶水代码。发布所有这些可能会使问题变得复杂,我觉得不需要理解面临的问题

编辑1

如果正在压缩的文件夹有5个文件,7zip将首先输出版权。然后它将输出文本Scanning。然后它将输出一行Creating archive at some location。然后它将处理每个文件,逐个输出每个文件的进度。通过这种方式,我们可以获得有关操作进度的持续反馈。

如果我执行powershell函数,那么我看到操作持续时间没有输出,然后一次看到所有输出。我没有得到7zip的反馈。我想模拟7zip作为一个独立的exe运行时显示的行为。

3 个答案:

答案 0 :(得分:1)

这对我有用:

& 7z.exe a -t7z -bsp1 $archive_name $src 2>&1 | Out-Host

-bsp1开关将progress information流重定向到stdout流。这是7z的一个特征。另请查看-bb开关。

2>&1将错误流重定向到stdout。这是PowerShell的一项功能。

  

-bs(设置输出/错误/进度行的输出流)切换语法

     

语法

     

-bs{o|e|p}{0|1|2}

{id} | Stream Type
................................
 o   | standard output messages
 e   | error messages
 p   | progress information
{N} | Stream Destination
................................
 0   | disable stream
 1   | redirect to stdout stream
 2   | redirect to stderr stream

答案 1 :(得分:0)

为什么不这样呢?如果你需要

function archive-folder ($src, $archive_name) {   
$origcolor = [console]::ForegroundColor
[console]::ForegroundColor = "yellow"
"archiving $src"
$command = "7z.exe a -t7z $archive_name $src"
iex $command    
[console]::ForegroundColor = $origcolor    
}

我琐碎的来电功能:

Function k
{
  dir c:\ps\ita
  Write-Host "Starting 7zippping from K function"
  archive-folder -archive_name c:\ps\pippo.7z c:\ps\ita
  Write-Host "7zipping from function k ended"
}

以及我在powershell控制台中看到的内容(黄色,来自archive-folder的输出)

  

ķ

    Directory: C:\ps\ita


Mode           LastWriteTime       Length Name
----           -------------       ------ ----
-a---    08/06/2011    19:26     5,502 MB ita.txt
-a---    28/05/1994    16:59   165,624 KB ITALIANO.A
-a---    28/05/1994    16:54    53,903 KB ITALIANO.B
-a---    28/05/1994    17:00   165,541 KB ITALIANO.C
-a---    08/06/2011    11:06    98,609 KB ITALIANO.D
-a---    28/05/1994    17:00    72,077 KB ITALIANO.E
-a---    28/05/1994    16:54    80,813 KB ITALIANO.F
-a---    28/05/1994    16:55    78,312 KB ITALIANO.G
-a---    28/05/1994    16:55     2,412 KB ITALIANO.H
-a---    08/06/2011    11:07   298,609 KB ITALIANO.I
-a---    28/05/1994    16:55     1,033 KB ITALIANO.J
-a---    28/05/1994    16:55     1,777 KB ITALIANO.K
-a---    28/05/1994    17:01    71,553 KB ITALIANO.L
-a---    08/06/2011    10:59   162,084 KB ITALIANO.M
-a---    28/05/1994    16:56    47,123 KB ITALIANO.N
-a---    28/05/1994    16:56    72,973 KB ITALIANO.O
-a---    08/06/2011    19:37   264,109 KB ITALIANO.P
-a---    28/05/1994    16:56    10,512 KB ITALIANO.Q
-a---    08/06/2011    19:38   327,348 KB ITALIANO.R
-a---    08/06/2011    19:40   566,512 KB ITALIANO.S
-a---    08/06/2011    10:57   184,719 KB ITALIANO.T
-a---    28/05/1994    16:57    19,378 KB ITALIANO.U
-a---    28/05/1994    16:57    61,552 KB ITALIANO.V
-a---    28/05/1994    16:57     1,334 KB ITALIANO.W
-a---    28/05/1994    16:57     1,368 KB ITALIANO.X
-a---    28/05/1994    16:57       533 B  ITALIANO.Y
-a---    28/05/1994    17:01     7,054 KB ITALIANO.Z
Starting 7zippping from K funztion
archiving c:\ps\ita

7-Zip 4.65  Copyright (c) 1999-2009 Igor Pavlov  2009-02-03

Scanning

Updating archive c:\ps\pippo.7z

Compressing  ITA\ITALIANO.H
Compressing  ITA\ITALIANO.C
Compressing  ITA\ITALIANO.F
Compressing  ITA\ita.txt
Compressing  ITA\ITALIANO.O
Compressing  ITA\ITALIANO.A
Compressing  ITA\ITALIANO.B
Compressing  ITA\ITALIANO.D
Compressing  ITA\ITALIANO.E
Compressing  ITA\ITALIANO.G
Compressing  ITA\ITALIANO.I
Compressing  ITA\ITALIANO.J
Compressing  ITA\ITALIANO.K
Compressing  ITA\ITALIANO.L
Compressing  ITA\ITALIANO.M
Compressing  ITA\ITALIANO.N
Compressing  ITA\ITALIANO.P
Compressing  ITA\ITALIANO.Q
Compressing  ITA\ITALIANO.R
Compressing  ITA\ITALIANO.S
Compressing  ITA\ITALIANO.T
Compressing  ITA\ITALIANO.U
Compressing  ITA\ITALIANO.V
Compressing  ITA\ITALIANO.W
Compressing  ITA\ITALIANO.X
Compressing  ITA\ITALIANO.Y
Compressing  ITA\ITALIANO.Z

Everything is Ok
7zipping from function k ended

答案 2 :(得分:0)

在我看来,你应该能够做到:

&7z.exe a -t7z $archive_name $src | write-verbose

除非有我遗漏的东西。