개체에서 실행되는 Powershell 명령의 출력 형식을 유지하는 방법은 무엇입니까?

개체에서 실행되는 Powershell 명령의 출력 형식을 유지하는 방법은 무엇입니까?

대본

개체 내부에 없을 때 "실시간/발생할 때"를 보는 것과 같은 방식으로 개체의 메서드 내에서 실행되는 powershell 명령의 출력을 보고 싶습니다.

원하지 않는 차이점을 설명하기 위해 2개의 스크립트를 보여 드리겠습니다. 첫 번째 스크립트는 commnad의 출력을 보여주고 두 번째 스크립트는 그렇지 않습니다. 둘 다 powershell을 열고 해당 디렉토리를 탐색하여 실행됩니다../<scriptname>.ps1

  1. 내용을 고려해 보세요 scriptA.ps1:
lxrun /install /y

다음과 같은 원하는 결과가 생성됩니다.

Warning: lxrun.exe is only used to configure the legacy Windows
Subsystem for Linux distribution. Distributions can be installed by
visiting the Windows Store: https://aka.ms/wslstore

This will install Ubuntu on Windows, distributed by Canonical and
licensed under its terms available here: https://aka.ms/uowterms

The legacy Windows Subsystem for Linux distribution is already
installed. 
  1. scriptB.ps1내용:
# runs single command
Class Object{
    runCommand(){
        lxrun /install /y
    }
}

# create object
[Object] $object = [Object]::new()

# execute command in method runCommand() of [Object] object
$object.runCommand()

출력이 전혀 표시되지 않습니다.

시도

모든 시도는 다음 스크립트 내에서 이루어집니다.<command here>

# runs single command
Class Object{
    runCommand(){
        `<command here>`
    }
}
  1. 선:
Write-Output (lxrun /install /y)

결과 출력:(출력 없음)


  1. 선:
Write-Host (lxrun /install /y)

결과 출력:내용은 정확하지만 읽을 수 있는 텍스트 형식이 손실/변경되었습니다.

W a r n i n g :   l x r u n . e x e   i s   o n l y   u s e d   t o  
c o n f i g u r e   t h e   l e g a c y   W i n d o w s   S u b s y s
t e m   f o r   L i n u x   d i s t r i b u t i o n .       D i s t r
i b u t i o n s   c a n   b e   i n s t a l l e d   b y   v i s i t i
n g   t h e   W i n d o w s   S t o r e :       h t t p s : / / a k a
. m s / w s l s t o r e             T h i s   w i l l   i n s t a l l 
U b u n t u   o n   W i n d o w s ,   d i s t r i b u t e d   b y   C
a n o n i c a l   a n d   l i c e n s e d   u n d e r   i t s   t e r
m s   a v a i l a b l e   h e r e :         h t t p s : / / a k a . m
s / u o w t e r m s             T h e   l e g a c y   W i n d o w s  
S u b s y s t e m   f o r   L i n u x   d i s t r i b u t i o n   i s 
a l r e a d y   i n s t a l l e d . 
  1. 선:
Write-Host (lxrun /install /y) | Out-Host

결과 출력: 시도 2와 동일합니다.

  1. 선:
Write-Host (lxrun /install /y) | Out-Default

결과 출력: 시도 2와 동일합니다.

  1. 선:
Write-Host (lxrun /install /y) | Out-String

결과 출력: 시도 2와 동일

  1. 선:
write-verbose (lxrun /install /y)

결과 출력:(출력 없음)

Write-Verbose : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Message'.
Specified method is not supported.
At F:\path to example script\example.ps1:30 char:23
+         write-verbose (lxrun /install /y)
+                       ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Write-Verbose], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.WriteVerboseCommand
  1. 선:
write-verbose (lxrun /install /y) -Verbose

결과 출력: 6과 동일(오류가 발생한 행에 -Verbose가 포함된 경우 제외)


  1. 선:
(lxrun /install /y) | Write-Host

결과 출력: 가독성이 더 좋아졌지만 여전히 표준은 아닙니다.

o   c o n f i g u r e   t h e   l e g a c y  W i n d o w s   S u b s y
s t e m   f o r   L i n u x   d i s t r i b u t i o n .


 D i s t r i b u t i o n s   c a n   b e   i n s t a l l e d   b y   v
i s i t i n g   t h e   W i n d o w s   S t o r e :


 h t t p s : / / a k a . m s / w s l s t o r e





 T h i s   w i l l   i n s t a l l   U b u n t u   o n   W i n d o w s
,   d i s t r i b u t e d   b y   C a n o n i c a l   a n d   l i c e
n s e d   u n d e r   i t s   t e r m s   a v a i l a b l e   h e r e
:


 h t t p s : / / a k a . m s / u o w t e r m s





 T h e   l e g a c y   W i n d o w s   S u b s y s t e m   f o r   L i
n u x   d i s t r i b u t i o n   i s   a l r e a d y   i n s t a l l
e d . ```
  1. 선:
Write-Verbose -Message (lxrun /install /y)

결과 출력:

Write-Verbose : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Message'. Specified method is not supported.
At G:/path to file\example.ps1:35 char:32
 +         Write-Verbose -Message (lxrun /install /y)
 +                                ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Write-Verbose], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.WriteVerboseCommand
  1. 선:
Write-Verbose -Message lxrun /install /y

결과 출력: 시도 9와 동일

  1. 선:
Write-Verbose -Message (lxrun /install /y) -Verbose

결과 출력: 시도 9와 동일(오류가 발생한 행에 -Verbose가 포함된 경우 제외)

  1. 기반댓글에 링크된 질문과 답변, 스크립트를 다음과 같이 수정했습니다.
# runs single command

#[CmdletBinding(SupportsShouldProcess=$true)]
[CmdletBinding()]
Param()
Class Object{    
    runCommand(){
        lxrun /install /y|Write-Verbose
    }
}

# create object
[Object] $object = [Object]::new()

# execute command in method runCommand() of [Object] object
$object.runCommand()

실행할 때 -Verbose 매개변수와 함께 호출됩니다 ./example.ps1 -Verbose. 검정색과 노란색 텍스트를 반환합니다.

VERBOSE: W a r n i n g :   l x r u n . e x e   i s   o n l y   u s e d   t o   >c o n f i g u r e   t h e
l e g a c y   W i n d o w s   S u b s y s t e m   f o r   L i n u x   d i s t >r i b u t i o n .
VERBOSE:
VERBOSE:
VERBOSE:  D i s t r i b u t i o n s   c a n   b e   i n s t a l l e d   b y   v >i s i t i n g   t h e
W i n d o w s   S t o r e :
VERBOSE:
VERBOSE:
VERBOSE:  h t t p s : / / a k a . m s / w s l s t o r e
VERBOSE:
VERBOSE:
VERBOSE:
VERBOSE:
VERBOSE:
VERBOSE:  T h i s   w i l l   i n s t a l l   U b u n t u   o n   W i n d o w s >,   d i s t r i b u t e d
b y   C a n o n i c a l   a n d   l i c e n s e d   u n d e r   i t s   t e r >m s   a v a i l a b l e
h e r e :
VERBOSE:
VERBOSE:
VERBOSE:  h t t p s : / / a k a . m s / u o w t e r m s
VERBOSE:
VERBOSE:
VERBOSE:
VERBOSE:
VERBOSE:
VERBOSE:  T h e   l e g a c y   W i n d o w s   S u b s y s t e m   f o r   L i >n u x
d i s t r i b u t i o n   i s   a l r e a d y   i n s t a l l e d .
VERBOSE:
VERBOSE:
VERBOSE:

내가 이해한 바에 따르면 인수를 Param()전달/흡수하기 위해 포함되어 있으며-Verbose[CmdletBinding()] cmdlet스크립트가 수행하는 "일반적인" 방식 대신 a 가 수행하는 방식으로 let 바인딩을 활성화합니다 .나는 여전히 그 차이가 무엇을 의미하는지 이해해야 합니다. 그리고 이 Write-Verbose 구현에서는 형식이 아직 정확하지 않거나 바람직하지 않습니다.

질문

와 같이 원래 형식을 잃지 않고 지연 없이 powershell 터미널에 명령 출력을 어떻게 작성합니까 scriptA.ps1?

메모

파서를 구축할 수도 있지만 아직 찾지 못한 더 효율적이고 빠른 솔루션이 있을 수 있다고 생각합니다.

답변1

결국 파서를 작성하는 것이 더 빠른 솔루션이라는 것이 밝혀졌습니다([반드시] 런타임 측면이 아니라 구축 측면에서). 내 검색 절차는 (아직) write..등을 사용하는 명령이 출력을 변경한 이유와 방법을 조사하지 않았기 때문입니다( 체재).

# runs single command
Class Object{
    runCommand(){
        $output = (lxrun /install /y)
        Write-Host $this.parseOutput($output) # return formating back to "normal"
    }

    # removes null characters and then replaces triple spaces with enters.
    [String] parseOutput([String] $output){

        # first remove all nulls
        $output = $output.Replace(([char]0).ToString(),'')

        # then replace all triple occurrences of spaces with newlines
        $output = $output.Replace(([char]32+[char]32+[char]32).ToString(),"`n")

        return $output
    }

}

# create object
[Object] $object = [Object]::new()

# execute command in method runCommand() of [Object] object
$object.runCommand()

이것은 문제를 "해결"/해결하지만 더 깊은 이해를 선호합니다. 따라서 누군가 설명할 수 있다면:

  1. 명령이 개체에서/에서 실행될 때 추가 nullspace문자가 추가되는 이유에 대해 크게 감사하겠습니다.
  2. 자체 작성된 메서드를 호출하지 않고 명령과 동일한 줄에서 수행할 수 있는 방법은 더 나은 솔루션을 찾습니다.

관련 정보