Introduction

忘備録。

よくあるのが、Visual Studio の vcvars64.bat とか。

Powershell 内でこれらのバッチを呼び出しても、バッチが別プロセスで実行されるため、バッチで定義された環境変数は呼び出し元に引き継がれない。
例えば、下記のような Powershell。

1
2
cmd.exe /c 'C:\Program Files (x86)\Intel\OpenVINO\2022.3.1\setupvars.bat'
Write-Host "OpenVINO_DIR: ${env:OpenVINO_DIR}"

OpenVINO の変数を設定するつもりだが実行結果は下記。

1
2
3
Python 3.10.8
[setupvars.bat] OpenVINO environment initialized
OpenVINO_DIR:

じゃあどうするか?

How to resolve?

バッチやシェルスクリプト内で実行した環境変数を呼び出し元に戻して設定すればいい。

Windows

1
2
3
4
5
6
7
8
9
10
11
12
function Call($batfile)
{
cmd.exe /c "call `"${batfile}`" && set > %temp%\vars.txt"
Get-Content "${env:temp}\vars.txt" | Foreach-Object {
if ($_ -match "^(.*?)=(.*)$") {
Set-Content "env:\$($matches[1])" $matches[2]
}
}
}

Call("C:\Program Files (x86)\Intel\OpenVINO\2022.3.1\setupvars.bat")
Write-Host "OpenVINO_DIR: ${env:OpenVINO_DIR}"

バッチファイルを cmd.exe の引数として実行し、かつ環境変数をファイルにリダイレクトする。
そのファイルを正規表現で解析し、呼び出し元の Powershell 内で設定しなおすだけ。

実行するとこうなる。

1
2
3
Python 3.10.8
[setupvars.bat] OpenVINO environment initialized
OpenVINO_DIR: C:\Program Files (x86)\Intel\OpenVINO\2022.3.1\\runtime\cmake

Linux

Linux の場合も似た感じ。
下記のシェルスクリプトで変数を定義していたとする。

1
2
#!/bin/bash +x
export TEST=hoge

source を活用して

1
2
3
4
5
6
7
8
9
10
11
12
function Call($shellfile)
{
/bin/bash -c "source ${shellfile} && printenv > /tmp/vars.txt"
Get-Content "/tmp/vars.txt" | Foreach-Object {
if ($_ -match "^(.*?)=(.*)$") {
Set-Content "env:\$($matches[1])" $matches[2]
}
}
}

Call("test.sh")
Write-Host "TEST: ${env:TEST}"

実行するとこうなる。

1
TEST: hoge