programing

파워셸에서 배치 스크립트를 어떻게 호출합니까?

telecom 2023. 9. 2. 07:59
반응형

파워셸에서 배치 스크립트를 어떻게 호출합니까?

여러 환경 변수를 설정하는 큰 일괄 처리 스크립트가 있습니다.powershell에서 배치 스크립트를 호출하여 내 스크립트와 powershell에서 설정한 환경 변수의 이점을 모두 얻을 수 있습니다.

PowerShell Community Extensions를 가져오면 배치 파일을 실행하는 Invoke-BatchFile 명령이 있지만 더 중요한 것은 배치 파일에 의해 수행된 모든 환경 변수 수정 사항을 유지한다는 것입니다. 예를 들어 다음과 같습니다.

>Invoke-BatchFile 'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat'
Setting environment for using Microsoft Visual Studio 2008 x86 tools.

이 아이디어는 다음 블로그 게시물에서 나온 것입니다.모든 것을 해결하는 것은 없습니다 – PowerShell 및 기타 기술

이것이 이 스크립트의 제 버전입니다.배치 파일(또는 네이티브 명령)을 호출하고 환경을 전파합니다.


업데이트: 이 스크립트의 개선되고 테스트된 버전은 다음과 같습니다.Invoke-Environment.ps1

<#
.SYNOPSIS
    Invokes a command and imports its environment variables.

.DESCRIPTION
    It invokes any cmd shell command (normally a configuration batch file) and
    imports its environment variables to the calling process. Command output is
    discarded completely. It fails if the command exit code is not 0. To ignore
    the exit code use the 'call' command.

.PARAMETER Command
        Any cmd shell command, normally a configuration batch file.

.EXAMPLE
    # Invokes Config.bat in the current directory or the system path
    Invoke-Environment Config.bat

.EXAMPLE
    # Visual Studio environment: works even if exit code is not 0
    Invoke-Environment 'call "%VS100COMNTOOLS%\vsvars32.bat"'

.EXAMPLE
    # This command fails if vsvars32.bat exit code is not 0
    Invoke-Environment '"%VS100COMNTOOLS%\vsvars32.bat"'
#>

param
(
    [Parameter(Mandatory=$true)] [string]
    $Command
)

cmd /c "$Command > nul 2>&1 && set" | .{process{
    if ($_ -match '^([^=]+)=(.*)') {
        [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
    }
}}

if ($LASTEXITCODE) {
    throw "Command '$Command': exit code: $LASTEXITCODE"
}

추신: PowerShell에 유사한 기능을 추가하기 위한 제안입니다. 점 소싱 개념을 cmd 파일로 확장합니다.

배치 스크립트를 PowerShell 스크립트로 변환할 수 있습니까?bat 파일을 실행하면 PowerShell의 환경 변수를 수정하지 않는 별도의 세션에서 실행됩니다.

환경 변수를 매우 원활하게 사용할 수 있습니다.

PS> Get-ChildItem env:

Name                           Value
----                           -----
ALLUSERSPROFILE                C:\ProgramData
APPDATA                        C:\Users\xyz\AppData\Roaming
CommonProgramFiles             C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)        C:\Program Files (x86)\Common Files
CommonProgramW6432             C:\Program Files\Common Files
COMPUTERNAME                   xyz
ComSpec                        C:\Windows\system32\cmd.exe
DXSDK_DIR                      D:\prgs\dev\Microsoft DirectX SDK (August 2009)\
FP_NO_HOST_CHECK               NO
HOMEDRIVE                      Z:
HOMEPATH                       \
...

PS> Get-Item env:path
Name  Value
----  -----
Path  c:\dev\CollabNet\SubversionClient;C:\Windows\system32;...

또는 짝수(훨씬 짧고 문자열만 반환):

PS> $env:path
c:\dev\CollabNet\Subversion Client;C:\Windows\system32;...

다음과 같이 환경 경로를 변경할 수 있습니다.

PS> $env:path += ";c:\mydir"

또한 다음과 같은 시스템 레벨에서 환경 변수를 설정할 수도 있습니다.

# fist arg = env variable name, second = value, third = level, available are 'Process', 'User', 'Machine'
PS> [Environment]::SetEnvironmentVariable('test', 'value', 'machine')

@Roman Kuzmin의 솔루션은 잘 작동하지만 명령어 출력을 null로 파이핑하면 사용자를 어둠에 빠뜨릴 수 있습니다.그래서 명령 출력이 정상적으로 표시되도록 몇 가지 수정을 했고, 대신 템플릿을 임시 파일에 연결하여 나중에 읽을 수 있도록 했습니다.

param
(
    [Parameter(Mandatory=$true)] [string]
    $Command
)
$VarsPath = [IO.Path]::GetTempFileName()
cmd /c "$Command && set > $VarsPath"
if (-not $LASTEXITCODE) {
    Get-Content $VarsPath | ForEach-Object {
        if ($_ -match '^([^=]+)=(.*)') {
            [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
        }
    }
}
Remove-Item $VarsPath

이름만 입력해도 Powershell에서 일괄 스크립트를 실행할 수 있지만, 도움이 되지 않습니다.배치 스크립트에 설정된 환경 변수는 해당 배치해당 배치가 실행되는 모든 항목에서만 표시됩니다.컨트롤이 Powershell로 돌아오면 환경 변수는 사라집니다.배치 스크립트를 실행할 수 있습니다.set그러나 마지막에 출력을 PSH 환경 변수로 구문 분석합니다.

언급URL : https://stackoverflow.com/questions/4384814/how-to-call-batch-script-from-powershell

반응형