WSL 2에서 PATH가 호스트 머신과 충돌하는 문제

WSL에 깔린 우분투에서 npx react-native run-android를 실행하다가 이런 오류를 마주쳤습니다.

-bash: /mnt/c/Program Files/nodejs/npm: /bin/sh^M: bad interpreter: No such file or directory

우분투에 bash가 없다니 무슨 상황일까요? 그리고 대체 어쩌다가 npm/mnt/c/Program Files/에서 실행되는 걸까요? 이 문제를 해결해 보려고 한참 동안 노력한 끝에(여기서 노력이란 StackOverflow를 뒤지는 것을 말합니다) 문제를 얼렁뚱땅 해결한 과정을 여기에 씁니다.

발단

때는 2017년, 마이크로소프트는 WSL과 호스트 머신 사이에 환경 변수를 공유하는 기능을 추가했습니다. API 토큰 같은 환경 변수들을 WSL에서도 그대로 사용할 수 있다는 것은 분명한 장점이었습니다.

전개

이 과정의 결과로 PATH 환경 변수도 윈도우와 WSL 머신 사이에 공유되기 시작했다는 것이 문제의 근원이었습니다. 제 WSL 머신에서 echo $PATH를 실행하면,

/home/heartade/.nvm/versions/node/v14.21.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:[...]:/mnt/c/Program Files/nodejs:/mnt/c/Program Files/JetBrains/IntelliJ IDEA Community Edition 2023.1/bin:[...]:/home/heartade/android/tools/bin:/home/heartade/android/platform-tools

위와 같이 윈도우의 PATH 환경 변수에 들어 있는 경로들이 우분투의 PATH에 붙어 있는 것을 확인할 수 있습니다.

위기

하지만 일반적으로는 PATH 환경 변수의 맨 앞에서부터 실행 파일을 찾게 되니 문제가 없지 않을까요? nvmnode 실행 파일의 경로를 PATH의 맨 앞에 붙이는걸요.

하지만 어쨌든 문제는 발생하고 있었습니다. 빌드 과정 중의 어딘가에서 프로세스가 윈도우 호스트로 탈출한 다음 sh를 찾아 헤매고 있었던 것입니다. 윈도우에서 node를 지워 버리는 방법도 있겠지만, 대부분 작업은 윈도우 호스트에서 하기 때문에 그럴 수 없었습니다.

절정

저는 결국 윈도우 PATH를 WSL 머신에서 삭제하는 방법을 찾아야 했습니다. 이는WSL에서 더 이상 code . 명령어를 쓸 수 없다는 슬픔을 감내해야 한다는 의미기도 했습니다.

WSL 머신에서 /etc/wsl.conf 파일을 열거나 만들고 다음과 같은 설정을 추가하면 윈도우 PATH 연동을 중단할 수 있습니다.

[interop]
appendWindowsPath=false

설정 변경 이후에는 호스트 머신에서 한 번 wsl --shutdown 명령으로 WSL 머신을 재시작해 줘야 합니다.

결말

이 글을 쓰면서 문제를 재현해 보기 위해 appendWindowsPath=false를 지워 봤는데, 정작 이번에는 문제가 재현되지 않았습니다. code . 명령어도 정상적으로 작동했습니다. 그간의 고생을 생각하면 허망할 따름이었습니다.

앞의 문제가 발생한 정확한 이유는 알 수 없게 되었지만, 개인적으로는 nvm이 실행되는 위치가 .bashrc이기 때문에 별도로 sh 프로세스가 실행된 경우 nodenpm이 윈도우 경로에서 실행되는 문제가 발생하는 것 아닌지 의심하고 있습니다.

이번엔 얼렁뚱땅 해결되었지만, 다음에 같은 문제가 발생하면 원인을 정확히 파악할 때까지 파고들어 보고 명확한 결론을 말씀드리도록 하겠습니다.

태그: #뚝딱뚝딱


Daniel Soohan Park (@heartade)

Follow this blog at Fediverse: @heartade@blog.heartade.dev

Follow my shorter shoutouts at Fediverse: @heartade@social.silicon.moe