1

考虑以下命令:

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:脚本.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,我还有其他执行某些命令行工具的功能。我在想这些函数中的每一个都可以返回真或假,这取决于是否使用正确的操作调用了该函数以及是否正确执行了命令行工具。

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

我第一次尝试解决这个问题是将命令执行语句写为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 运行时显示的行为。

4

3 回答 3

6

这对我有用:

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

-bsp1开关将流重定向到progress informationstdout。这是7z的一个特点。还要看-bb开关。

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

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

句法

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

{id} | 流类型
...................................
 ○ | 标准输出消息
 电子| 错误信息
 p | 进度信息
{N} | 流目的地
...................................
 0 | 禁用流
 1 | 重定向到标准输出流
 2 | 重定向到标准错误流
于 2016-07-15T16:07:28.327 回答
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
于 2012-11-23T21:17:50.217 回答
0

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

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

除非我缺少什么。

于 2012-11-23T21:51:44.090 回答