ハマった
Windows batスクリプトの知見
- setlocal / endlocal しない限り、環境変数のスコープが共有される
実験
構成
|`- main.bat `- subdir `- sub.bat
main.bat
@echo off echo [main.bat] current directory: %CD% call .\subdir\sub.bat echo [sub.bat] current directory: %CD%
sub.bat
@echo off echo [sub.bat] current directory: %CD% rem sub.batがいるディレクトリまで移動 cd %~dp0 echo [sub.bat] current directory: %CD%
実行結果
E:\work\example>main.bat [main.bat] current directory: E:\_work\example [sub.bat] current directory: E:\_work\example [sub.bat] current directory: E:\_work\example\subdir [main.bat] current directory: E:\_work\example\subdir E:\work\example\subdir>
子供のbatでcdした結果はコマンドプロンプト含む呼び出し元にも影響。
Windows batで元のCDを残す
【1: setlocal / endlocalで環境変数のローカルスコープをリセット】
sub.bat
@echo off setlocal echo [sub.bat] current directory: %CD% rem sub.batがいるディレクトリまで移動 cd %~dp0 echo [sub.bat] current directory: %CD% endlocal
実行結果
E:\work\example>main.bat [main.bat] current directory: E:\_work\example [sub.bat] current directory: E:\_work\example [sub.bat] current directory: E:\_work\example\subdir [main.bat] current directory: E:\_work\example E:\work\example>
【2: CDを記憶し帰り際にCDしなおす】
sub.bat
@echo off echo [sub.bat] current directory: %CD% set PARENT_CD=%CD% rem sub.batがいるディレクトリまで移動 cd %~dp0 echo [sub.bat] current directory: %CD% cd %PARENT_CD%
実行結果
E:\work\example>main.bat [main.bat] current directory: E:\_work\example [sub.bat] current directory: E:\_work\example [sub.bat] current directory: E:\_work\example\subdir [main.bat] current directory: E:\_work\example E:\work\example>
Linux bashシェルスクリプトの知見
- /bin/bashで別プロセスで コールされる(別プロセスが立ち上がる)ときは親プロセスのスコープを引き継ぎ、プロセスを戻るときに環境変数破棄
.
やsource
で呼び出されたら親プロセス内で処理されたことになり、共有スコープとなる(戻っても変更内容引継ぎ)
実験
ディレクトリ構成
|`- main.sh `- subdir `-sub.sh
main.sh
#!/bin/bash echo [main]pwd: `pwd` echo cd ~/test /bin/bash ./subdir/sub.sh echo [main]pwd: `pwd` echo cd ~/test . subdir/sub.sh echo [main]pwd: `pwd` echo cd ~/test source subdir/sub.sh echo [main]pwd: `pwd`
sub.sh
#!/bin/bash echo [sub]pwd: `pwd` cd ~/test/subdir echo [sub]pwd: `pwd`
実行結果
yu@yu:~/test$ ./main.sh [main]pwd: /home/yu/test [sub]pwd: /home/yu/test [sub]pwd: /home/yu/test/subdir [main]pwd: /home/yu/test [sub]pwd: /home/yu/test [sub]pwd: /home/yu/test/subdir [main]pwd: /home/yu/test/subdir [sub]pwd: /home/yu/test [sub]pwd: /home/yu/test/subdir [main]pwd: /home/yu/test/subdir
/bin/bashで蹴られたときだけcdしたものが自動で破棄。
また、$0 で見えるキックされたスクリプト名も、プロセスを共有していると親のものが参照される。