programing

자세한 출력으로 PowerShell 스크립트를 실행하는 방법은 무엇입니까?

sourcejob 2023. 9. 11. 21:38
반응형

자세한 출력으로 PowerShell 스크립트를 실행하는 방법은 무엇입니까?

스크립트의 각 행의 명령어와 출력이 모두 출력되도록 파워쉘 스크립트를 실행할 수 있는 방법이 있는지 궁금합니다.를 들어,를어은과이쓸다서다쓸이er과h를d,어nhe,u에서bash -x myscript아니면 a를 놓거나,set -x대본 맨 위에.서을다합니다.@echo off대본의 맨 위에 전통적으로 남겨져 있었습니다.PowerShell에 이러한 구성 요소와 동등한 기능이 있습니까?

내가 시도해 본 것들:입니다.powershell -? | sls verbose 것도

@JamesKo, 잘못된 질문을 하면 오답:-(. 여기에 여러 사람들이 (a) Linux 노출 부족과 (b) 장황한 용어 사용에 근거하여 선의의 답변을 제시합니다.다음에서는 이 주제에 대해 Linux가 PowerShell과 어떤 관련이 있는지 설명해 드리지만, 급하신 분들은 마지막에 자유롭게 답변을 드릴 수 있습니다. :-

배경

PowerShell에서 verbose는 매우 구체적인 의미를 갖는데, PowerShell 사용자 페이지는 이에 대해 다소 모호합니다.

명령에 의해 수행된 작업에 대한 상세 정보를 표시합니다.이 정보는 추적 또는 트랜잭션 로그의 정보와 유사합니다.이 매개 변수는 명령이 상세 메시지를 생성할 때만 작동합니다.

심지어 당신이 원하는 것처럼 들리는데요...이것을 리눅스 문서와 비교해 보겠습니다.set -x리눅스의 취향에 따라 이것(맨 페이지 프로젝트에서)이 될 수도 있습니다.

셸은 명령을 확장한 후 실행하기 전에 각 명령에 대한 추적을 표준 오류에 기록해야 합니다.

또는 이것(gnu에서)..

명령어, 대소문자 명령어, 명령어 선택, 명령어 확장 후 및 실행 전에 명령어와 관련 인수 또는 관련 단어 목록에 대한 산술을 인쇄합니다.

질문의 첫번째 줄은 명확하고 간결하게 이것들에 동의합니다.그러나 PowerShell의 자세한 내용은 다릅니다.를 켜는 입니다. 서,한과 라 할 수 .-Verbose줄치는는$VerbosePreference)은 단순히 variable로 출력합니다 (을 제공하는 처럼, 스트림,스트림, 스트림, 스트림, 스트림등의 합니다.(리눅스가 stdout과 stderr의 두 스트림을 제공하는 것처럼, PowerShell은 출력 스트림, 오류 스트림, 경고 스트림, 상세 스트림, 디버그 스트림 등의 여러 스트림을 제공합니다.할 수 . 를 들어, Linux한로다수할을와다,수enu할n한로hneoseu한nkx을tnl 예를 들어,commands 4>&1예를 들어, 상세 스트림을 stdout에 병합하려면(PowerShell One-Liner의 기본 쓰기 스트림 섹션에서 PowerShell의 여러 출력 스트림에 대해 자세히 확인할 수 있습니다.) 데이터 액세스, 처리쓰기와 좋은 빠른 참조 자료는 PowerShell Punctuation에 대한 전체 가이드입니다.)

더 앤서

Set-PSDebug 명령을 사용하면 bash-equivalent 추적이 가능합니다.추적 세부 정보를 조정할 수도 있습니다.-Trace매개 변수.우선, 사용하기 전에 제어 장치가 여기 있습니다.Set-PSDebug:

PS> Get-PSDepth
0

이 1일 때 코드의 각 줄을 실행할 때 얻을 수 있습니다. 예:

PS> Set-PSDebug -Trace 1
PS> Get-PSDepth
DEBUG:    1+  >>>> Get-PSDepth
DEBUG:  141+  >>>> {
DEBUG:  142+   >>>> $nest = -1
DEBUG:  143+   >>>> $thisId = $pid
DEBUG:  144+  while ( >>>> (ps -id $thisId).Name -eq 'powershell') {
DEBUG:  145+    >>>> $thisId = (gwmi win32_process -Filter "processid='$thisId'").ParentProcessId
DEBUG:  146+    >>>> $nest++
DEBUG:  144+  while ( >>>> (ps -id $thisId).Name -eq 'powershell') {
DEBUG:  148+   >>>> $nest
0
DEBUG:  149+  >>>> }

이 2인 경우 변수 할당 및 코드 경로도 얻을 수 있습니다.

PS> Set-PSDebug -Trace 2
PS> Get-PSDepth
DEBUG:    1+  >>>> Get-PSDepth
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:  141+  >>>> {
DEBUG:     ! CALL function 'Get-PSDepth'  (defined in file 'C:\Users\msorens\Documents\WindowsPowerShell\profile.ps1')
DEBUG:  142+   >>>> $nest = -1
DEBUG:     ! SET $nest = '-1'.
DEBUG:  143+   >>>> $thisId = $pid
DEBUG:     ! SET $thisId = '9872'.
DEBUG:  144+  while ( >>>> (ps -id $thisId).Name -eq 'powershell') {
DEBUG:  145+    >>>> $thisId = (gwmi win32_process -Filter "processid='$thisId'").ParentProcessId
DEBUG:     ! SET $thisId = '10548'.
DEBUG:  146+    >>>> $nest++
DEBUG:     ! SET $nest = '0'.
DEBUG:  144+  while ( >>>> (ps -id $thisId).Name -eq 'powershell') {
DEBUG:  148+   >>>> $nest
0
DEBUG:  149+  >>>> }

쓴가 한 의 입니다 한 의 입니다 은 가 Get-PSDepth을 . , 합니다.DEBUGprefix,출력과 되며, 이 접두사만 줄, 즉과며이우단의다를은제다xt은의e단,제e과e이,dhgmxt,0.

스크립트에서 언제든지 아래 내용을 사용할 수 있습니다.

$Verbose Preferences="계속"

참고: 셸은 상승 모드에서 열어야 합니다.

아래 스크린샷은 참고용입니다.

$VerbosePreference

도움이 되길 바랍니다.

변수를 할 수 PowerShell 가 / 에서 를 할 해야 을 해야 을 가 [CmdletBinding()] param ()매개변수가 없어도 상관없습니다.

스크립트 예제:테스트 출력.ps1

[CmdletBinding()] param ()
Write-Host "Test output on OS $($Env:OS)"
Write-Verbose "Test VERBOSE output on OS $($Env:OS)"
  1. PowerShell에서 스크립트 실행:
PS C:\> .\Test-Output.ps1 -Verbose
  1. Linux의 PowerShell에서 스크립트 실행:
/$ pwsh
PS /> ./Test-Output.ps1 -Verbose
  1. Windows에서 PowerShell.exe를 사용하여 스크립트를 실행합니다.
C:\> powershell.exe Test-Output.ps1 -Verbose
  1. Windows에서 pwsh.exe PowerShell Core를 사용하여 스크립트를 실행합니다.
C:\> pwsh.exe Test-Output.ps1 -Verbose
  1. Linux에서 pwsh PowerShell Core를 사용하여 스크립트를 실행합니다.
/$ pwsh Test-Output.ps1 -Verbose

Windows에서의 출력 예:

Test output on OS Windows_NT
VERBOSE: Test VERBOSE output on OS Windows_NT

Linux에서의 출력 샘플:

Test output on OS 
VERBOSE: Test VERBOSE output on OS 

참고: 이 답변은 원래 Windows Powershell에서 실행 성공 여부와 관계없이 특정 명령에 대한 정보를 출력해야 하는 중복 질문에 대한 응답으로 게시되었습니다.

Michael Sorens의 도움이 되는 답변을 보완하고 자세히 설명합니다.

제한이 있는 경우 를 사용하여 PowerShell 스크립트 문을 실행하기 전에 에코할있습니다. 그러나 에코된 명령확장되지 않는다는 에서 /보다는 의 / 옵션에 가깝습니다. 자세한 내용은 다음과 같습니다.

# Start tracing statements.
Set-PSDebug -Trace 1

try 
{

  # Sample command
  cmd /c echo 'hi there' $HOME

}
finally {
  Set-PSDebug -Trace 0 # Turn tracing back off.
}

위의 결과는 다음과 같습니다.

DEBUG:    4+  >>>> cmd /c echo 'hi there' $HOME
"hi there" C:\Users\jdoe
DEBUG:    6+  >>>> Set-PSDebug -Trace 0 # Turn tracing off.

이 접근 방식은 추가적인 노력이 거의 필요하지 않지만 한계는 다음과 같습니다.

  • 추적 문의 접두사를 제어할 수 없습니다.(예를 들면DEBUG: 4+ >>>> ,어디에4는 라인 번호입니다.

  • 추적을 항상 끄면 추적 문도 생성됩니다.

  • 추적 출력을 캡처하거나 억제할 수 있는 방법은 없습니다. 추적 출력은 항상 호스트(콘솔)에 인쇄됩니다. 그러나 PowerShell의 CLI를 통해 PowerShell 외부에서 캡처할 수 있습니다. 이 답변을 참조하십시오.

  • PowerShell 7.2에서는 라인 연속을 사용하여 여러 라인에 걸쳐 있는 명령어의 번째 라인만 메아리를 쳤습니다(GitHub 이슈 #8113 참조).

  • 아마도 가장 중요한 것은 메아리되는 문이 문자 그대로의 소스 코드 표현이므로 확장되지 않은 변수 참조 및 식을 포함할 수 있습니다.$HOME위의 예에서

    • GitHub issue #9463은 확장된 값(즉, 변수와 식이 그 값으로 대체됨)을 제안합니다.set -x인에bash를 들면예를 들어.
    • 어쨌든 인수가 항상 문자열인 외부 프로그램에 대한 호출은 가능하지만 PowerShell 명령에 대한 호출은 임의의 인수를 지원하는 것이 과제입니다.모든 것이 충실한 문자열 리터럴 표현을 갖는 것은 아니지만, 확장되지 않은 값보다 인간 눈알 전용 문자열 표현도 거의 틀림없이 더 좋습니다.

확장된 인수 값보거나 출력 형식/대상을 제어해야 하는 경우:

참고:

  • 보안 위험이 내재되어 있고 더 안전한 옵션을 사용할 수 있으므로 일반적으로 () 피해야 하지만,iex 여기서는 항상 그렇듯이 원하지 않는 명령어가 주입되지 않도록 전달되는 문자열에 들어갈 내용을 완전히 제어해야 합니다.

  • 솔루션에서는 상위 확장(string-interpolation)을 사용하여 전달할 문자열을 구성해야 합니다. 이렇게 하면 결과 명령줄이 실행될 때 리터럴 인수포함되므로 명령행을 에코하면 실행 파일의 호출 내용과 인수의 전체 그림이 그려집니다.

    • 위에서 언급한 바와 같이, 이는 다음과 같은 외부 프로그램을 호출하는 경우에만 강력하게 가능합니다.msbuild.

후 하는 합니다 을 을 합니다 을 하는 을 Invoke-Expression:

# !! IMPORTANT:
# !! Only pass *trusted* strings to this function - the
# !! argument is blindly passed to Invoke-Expression.
function Invoke-AfterEchoing {
  param([string] $commandLine)

  # Echo the command line to be executed,
  # using the verbose output stream in this example:
  Write-Verbose -Verbose "Executing: $commandLine"

  Invoke-Expression $commandLine

}

이제 명령줄 문자열을 구성하여 도우미 기능에 전달할 수 있습니다.

Invoke-AfterEchoing @"
& "$msbuild" .\blabBlah.csproj /t:Clean
"@


Invoke-AfterEchoing @"
& "$msbuild" .\blabBlah.csproj /t:Build /p:Configuration=Dev
"@

참고:

  • 확장 가능한 여기 문자열(@"<newline>...<newline>"@ 따옴표를 하는 데 는 문자열 내부 따옴표를 단순화하는 데 사용됩니다.

    • 확장 가능한 형식을 선택하면 실행 경로와 모든 인수가 앞으로 확장되므로 결과 문자열에 해당하는 리터럴 값으로 포함되어 문자열을 반향하면 모든 실제 값이 표시됩니다.
  • &, 호출 연산자는 호출에 사용됩니다.msbuild, 그것의 경로가 인용되는 것을 고려할 때, 통사적으로 필요한 것이고, 다음으로 필요한 것은.$msbuild에는 공백이 있는 경로가 들어 있습니다.

출력은 다음과 같습니다.

VERBOSE: Executing: & "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin" .\blabBlah.csproj /t:Clean
# ... (output)

VERBOSE: Executing: & "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin" .\blabBlah.csproj /t:Build /p:Configuration=Dev
# ... (output)

실제로 모든 PowerShell CMDLET에는 Verbose 태그가 내장되어 있습니다.예를 들어 다음과 같은 작업만 수행하면 됩니다.

Test-Connection -ComputerName www.google.com -Verbose

여기까지입니다.이게 도움이 됐으면 좋겠습니다.

스크립트에서 write-verbose를 사용하는 경우 자동으로 발생합니다.

그러나 함수에서 세부 출력을 수동으로 작성해야 하는 경우 각 함수가 세부 플래그와 함께 호출되는지 수동으로 확인해야 합니다.이 작업은 다음과 같이 수행할 수 있습니다.checking$PSCmdlet.MyInvocation.BoundParameters["Verbose"]당신의 기능 안에서.

언급URL : https://stackoverflow.com/questions/41324882/how-to-run-a-powershell-script-with-verbose-output

반응형