programing

배치 파일에서 호출할 때 PowerShell 스크립트가 고착되어 종료되지 않음

mailnote 2023. 8. 4. 23:14
반응형

배치 파일에서 호출할 때 PowerShell 스크립트가 고착되어 종료되지 않음

웹 사이트에 연결하고 반환된 데이터를 구문 분석하는 PowerShell 스크립트가 있습니다(이전에 업로드한 SQL 파일을 웹 사이트의 데이터베이스로 가져오는 작업).는 PowerShell 파일을 사용합니다.wget나중에 네이티브 기능으로 대체할 수도 있습니다.

가져오기 프로세스는 스크립트라는 타사 프로그램에 의해 실행되는 스크립트에 포함됩니다.FTP.

스크립트는 다음과 같이 단일 .bat 파일에서 호출하면 정상적으로 실행됩니다.

powershell  "& "C:\data\etc\run_import_script.ps1"
exit %ERRORLEVEL%

그러나 대스크립트 내에서 이 .bat 파일을 호출할 때FTP 컨텍스트는 다음과 같습니다.

  • PowerShell 스크립트가 실행됩니다.원격 가져오기 스크립트가 호출될 때마다 직접 이메일을 보내는 것을 확인했습니다.
  • PowerShell이 종료되지 않고 스크립트 실행이 중단됩니다.Ctrl+C를 사용하여 전체를 취소할 수 있지만 다음 명령은 실행되지 않습니다.

배치 파일을 다음으로 변경할 때:

start powershell  "& "C:\data\etc\run_import_script.ps1"
exit %ERRORLEVEL%

콘솔에서 PowerShell 스크립트를 실행하면 작동하지만 PowerShell이 반환하는 오류 수준을 파악할 수 없습니다.

스크립트에서 PowerShell을 호출해 보았습니다.FTP를 직접 사용하여 배치 파일을 바이패스하지만 결과는 동일합니다.그냥 막힙니다.

PowerShell을 사용하여 은 다음과 .Write-Output또는Write-Host표시되지 않습니다.

모든 프로그램은 동일한 사용자 아래에서 실행됩니다.

어떻게 해야 할지 생각나는 사람?

이 변형은 사용자에게 적합할 수 있습니다.

powershell -NoProfile -Command "C:\data\etc\run_import_script.ps1; exit $LASTEXITCODE" < NUL

http://thepowershellguy.com/blogs/posh/archive/2008/05/20/hey-powershell-guy-how-can-i-run-a-powershell-script-from-cmd-exe-and-return-an-errorlevel.aspx 에서 발췌

제 경험에 따르면 PowerShell.exe는 -File 스위치를 사용하여 배치 파일 또는 셸 스크립트 내에서 예측 가능한 방식으로 스크립트를 쉽게 실행할 수 있습니다.시작 명령을 사용할 필요가 없습니다.

은 해야할중것추것다입니는가하은요한다▁the것▁append를 추가하는 것입니다.

< nul

배치 파일 내에서 명령줄로 이동합니다.제가 조사한 바에 따르면 PowerShell은 -File 스위치를 통해 표시된 스크립트에서 명령을 실행한 다음 표준 입력에서 추가 PowerShell 명령을 기다리는 것으로 나타났습니다(-Command 스위치를 사용한 간단한 실험에서도 유사한 동작이 입증되었습니다).표준 입력을 null로 리디렉션하면 PowerShell이 스크립트 실행을 마치고 표준 입력에서 "파일 끝 읽기"를 마치면 PowerShell이 종료됩니다.

는 Cygwin을 합니다.

< /dev/null

를 들어, 저는 과 같은 셸 의 PowerShell 한 적이 .

PowerShell.exe -ExecutionPolicy RemoteSigned -File $_powershellscriptpath $_firstscriptparameter < /dev/null

만약 당신의 경험이 저와 달랐다면 댓글을 달아주세요. - 고든

/WAIT 매개 변수를 추가해 보십시오.PowerShell 스크립트가 완료될 때까지 .bat를 계속 기다립니다.

START /WAIT powershell "& "C:\data\etc\run_import_script.ps1"

우리도 비슷한 문제가 있었습니다."명령" 및 "매개 변수"를 입력할 수 있는 상자가 있는 소프트웨어에서 powershell 앱을 호출하려고 했지만 powershell이 성공적으로 실행되었습니다(영향을 받는 파일이 업데이트된 것을 볼 수 있었습니다).

마지막으로 동료가 Command가 다음과 같이 필요하다는 것을 이해하는 데 도움을 주었습니다.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 

매개변수:

-ExecutionPolicy unrestricted -Command "& {C:\scripts\apps\EDI\Test.ps1; [Environment]::Exit(1)}"

우리의 경우에는 사용하는 것이 중요했습니다.[Environment]::Exit(1)Exit 1저는 Exit가 단순히 스크립트를 종료한 것이지 Powershell 자체를 종료한 것이 아니라고 생각합니다.

powershell.exe 명령의 출력을 캡처하려면 /B 매개 변수를 사용하여 프로세스를 동일한 명령 셸에서 실행할 수도 있습니다.

우리는 방금 이 문제의 아주 이상한 예를 보았습니다.이 포함된 입니다.powershell.exe -command ...로컬에서 정상적으로 실행되었지만 msdeploy -postSync 명령의 컨텍스트에서 배치 파일을 실행할 때 위에서 설명한 대로 실행이 중단되었습니다.로 한 후에.process.Kill() 종료하기 PowerShell을 했습니다.START /WAIT /B PowerShell.exe ..

이게 왜 효과가 있는지는 모르겠지만, 효과는...

파일에 있는 내용이 정확하게 일치하지 않으면 따옴표가 일치하지 않기 때문입니다.파워셸이 마지막 견적을 기다리고 있습니다.

PowerShell은 이러한 방식으로 호출될 때 이상한 동작을 합니다.즉, powershell.exe에 전달되는 명령줄 인수는 실행할 스크립트로 처리하지 않습니다.대신 실행 명령으로 처리합니다.이는 powershell.exe의 기본값이 -command이기 때문입니다. 자세한 내용은 powershell.exe /?를 참조하십시오.

C:\>powershell "'Hello'"
Hello

실행할 스크립트를 "소스"하기 위해 영리한 입력 문자열을 구성해야 합니다.

C:\>powershell ". .\test.ps1"
Hello, World!

출력의 경우 스크립트가 제대로 실행되면 STDOUT를 캡처하거나 스크립트와 일치하는 것이 문제가 됩니다.

전체 예제

테스트 배트

@echo off
powershell.exe ". .\test.ps1"

test.ps1

"Hello, World!"

다음 명령을 실행합니다.

test.bat > test.txt

그리고 출력이 캡처되었는지 확인합니다.

C:\>type test.txt
Hello, World!

제가 장담하는 문제는 Powershell 프로세스가 스크립트를 실행한 후에도 계속 실행된다는 것입니다.이는 종료되지 않았기 때문에 종료 코드가 없음을 의미합니다.C#에서 완료되면 작업을 수행하는 Powershell 스크립트를 실행하려고 할 때 유사한 문제가 발생합니다. 단, 완료되지 않는 경우만 제외하고는...

해키, 하지만 내가 찾은 유일한 해결책은Stop-Process -processname powershell.ps1 스크립트의 끝에 있습니다.이렇게 하면 PowerShell 프로세스(그리고 안타깝게도 열려 있는 모든 PowerShell 창)가 중지되지만 작동하는 것 같습니다.스크립트에도 사용할 수 있습니다.

정확히 문제가 있었습니다. 파워셸 스크립트를 다른 시스템에 통합하려고 했는데 계속 시간 초과 오류가 발생했습니다.아마도 고든 스미스가 언급한 문제 때문에 그의 해결책이 효과가 있을지도 모릅니다.하지만 저는 스크립트 자체에서 스크립트를 완벽하게 제어하는 것을 선호하며, 스크립트가 호출되는 방식에 의존하지 않습니다.

$pid는 PID를 가진 변수에 내장되어 있습니다.다음은 현재 파워셸 프로세스를 종료하고 다른 프로세스는 그대로 유지합니다.이렇게 하면 누구나 스크립트를 정상적으로 호출할 수 있으며 예상대로 작동합니다.

Stop-Process $pid

.ps1 스크립트(또는 원하는 프로세스 종료의 변형)의 끝에 'filename' 명령을 추가하기만 하면 됩니다.Powershell은 종료하라는 지시를 받지 않았기 때문에 스크립트 끝에서 계속 실행됩니다(PS 또는 ISE에서 실행될 때는 스크립트 끝에서 자동 종료되지만 DOS 셸을 통해 실행될 때는 종료되지 않습니다).

언급URL : https://stackoverflow.com/questions/2041799/powershell-script-gets-stuck-doesnt-exit-when-called-from-batch-file

반응형