powershell - 从Powershell函数内部的外部命令流输出

标签 powershell powershell-3.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

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

The script.ps1 will be coordinating this flow. Backup the database (mongodb generates files for each collection of the db). Archive the database backup. Upload the archive to S3. Each of these steps will be done by a separate function in common.ps1. The script.ps1 will only contain the glue code. Posting all this might have complicated the question and I felt wasn't needed to understand the issue am facing



编辑1

如果压缩的文件夹有5个文件,则7zip将首先输出版权。然后它将输出文本Scanning。然后它将输出一行Creating archive at some location。然后它将处理每个文件,逐个输出每个文件的进度。这样,我们就不断获得有关操作进度的反馈。

如果执行powershell函数,则在操作期间看不到任何输出,然后立即看到所有输出。我没有收到7zip的反馈。我想模拟7zip作为独立exe运行时显示的行为。

最佳答案

这对我有用:
& 7z.exe a -t7z -bsp1 $archive_name $src 2>&1 | Out-Host
-bsp1 开关将progress information流重定向到stdout流。这是7z的功能。还要看看 -bb 开关。
2>&1将错误流重定向到stdout。这是PowerShell的功能。

-bs (Set output stream for output/error/progress line) switch Syntax

Syntax

-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

关于powershell - 从Powershell函数内部的外部命令流输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13535567/

相关文章:

powershell - 获取 ADUser-Identity

powershell - 无法使用 powershell 从 Octopus 库访问 ssl 证书作为 X509Certificate2 对象

powershell - Powershell更换行为

powershell - 是我还是Powershell无法读取数字6-9(1-52)的范围?

powershell - 如何在 powershell 中使用 GetWindowText API 函数?

powershell - 选择对象为空错误?

powershell - 调用/设置名称中带有变量的变量

PowerShell:命令 "Get-ChildItem IIS:\Sites"导致错误

powershell - 测试命令匹配结果为 false 或 true

powershell-3.0 - Start-Process 系统找不到指定的文件