代码之家  ›  专栏  ›  技术社区  ›  Astora

Powershell-在错误位置写入主机打印

  •  2
  • Astora  · 技术社区  · 2 年前

    我的代码具有以下功能:

    function status{
        if ($args[0] -eq "Stopped"){
            Write-Host -NoNewline "Stopped" -fore red
        .....
        }
    }
    

    ...
    Write-Host "$($count)) $($i.DisplayName)   STATUS: $(status $i.State)"
    ...
    

    脚本执行后的结果是:

    停止

    为什么“Stopped”在行的开头?有人能帮我吗? 该功能仅用于更改文本颜色。作为示例 -fore red 是停止值。

    1 回复  |  直到 2 年前
        1
  •  2
  •   Santiago Squarzon    2 年前

    ANSI Escape sequences 但是它在旧的终端中不起作用。我不相信这是否可能结合 Write-Host 如果是的话,我认为这是一项极其乏味的任务。

    function status {
        $ansi = switch($args[0]) {
            Stopped { "$([char] 27)[91m" }
            Running { "$([char] 27)[32m" }
        }
        $ansi + $args[0]
    }
    
    foreach($state in 'Running', 'Stopped') {
        $count++
        $i = [pscustomobject]@{ state = $state; displayname = 'Hello!' }
        Write-Host "$($count)) $($i.DisplayName)   STATUS: $(status $i.State)"
    }
    

    example

        2
  •  2
  •   mklement0    2 年前

    Santiago Squarzon's helpful answer ; 让我用一个解释来补充它 你尝试了什么

    为什么“Stopped”在行的开头?

    原因是 Write-Host 成功 output stream 因此不会从您的 status

    相反 写入主机 主办 信息 流), 之前

    自子表达式(通过 $(...) )正在评估 第一 在可扩展字符串(或一般命令)中:

    • 打电话给你的 地位 开始 该行的。

    • 只有这样,外部 写入主机 调用执行,这是由于内部调用的 -NoNewLine 切换-在同一行打印, 打印了什么函数,以及 $(status $i.State) ,由于 空字符串 .

    一个简单的例子可以说明这个问题:

    Write-Host "foo: >>$(Write-Host bar)<<"
    

    输出:

    bar         # The inner Write-Host printed right away.
    foo >><<    # $(Write-Host bar) produced no success output
    

    圣地亚哥的解决方案通过替换 写入主机 通过发送字符串(隐式)在函数内部调用 到成功输出流 ,使其成为该子表达式的函数“返回值” 扩展到,并生成此字符串 有色的 ,需要ANSI/VT转义序列。

    注意,虽然 "$([char] 27)" 中需要 要在可扩展字符串中嵌入ESC字符, PowerShell(核心)7+ "`e"

    而且 PowerShell(核心)7.2+ automatic $PSStyle variable ,虽然更详细,但提供了一种更具描述性的方式来嵌入ANSI/VT转义序列;例如。:

    # Prints only the word "green" in green.
    "It ain't easy being $($PSStyle.Foreground.Green)green$($PSStyle.Reset)."
    

    • 如上例所示,如果将带有ANSI/VT序列的字符串发送到成功输出流,则颜色为 $PSStyle.Reset

    • 相比之下,如果 打印字符串,重置颜色 .