Sudo pip install은 안돼요!

Chullin
10 min readJun 20, 2018

--

Photo by Esteban Lopez

안녕하세요. 개발자 Chullin입니다.

오늘의 주제는 pip과 따로 떼어두기 어려운 sudo 입니다.

시간에 쫓기는 파이썬 개발자분들을 위해, 초두와 말미에 짧은 요약을 걸어두었습니다. 혹시 제가 잘못 쓴 부분이 있다면, 편안히 댓글 달아주시면 감사드리겠습니다!

TL; DR

  • pip 으로 패키지 설치할 때, sudo는 위험하니 절대 쓰지 맙시다.
  • 대신 가상환경 패키지 매니저를 설치하고 가상환경을 활용합시다.
  • pip 개발자도, 특권이 필요한 경로를 디폴트 경로로 설정한 것에 대해후회한다고 합니다.

PermissionError : pip 유저의 첫 장애물

pip을 통해서 패키지 설치를 하시는 초보 분들은 주로 다음과 같은 흐름을 거쳐서 패키지 설치를 진행하게 됩니다.

  • 패키지를 설치하고자 합니다.(저의 경우, pillow라는 이름의 패키지입니다.)
pip install Pillow
  • 설치 중, PermissionError가 뜹니다.
PermissionError: [Errno 13] Permission denied: ‘설치_경로’
  • 당황스럽고 답답한 마음에, 구글링을 해본 후, 제일 먼저 나온 sudo 해결책을 취합니다.
sudo pip install Pillow
  • 그러자, PermissionError없이 원하는 Pillow 패키지를 설치할 수 있었습니다.
Sucessfully Installed Pillow.

하지만 좀 찜찜합니다. 스택오버플로우, 레딧 등에서 sudo 가급적 사용하지 말라는 글들에 ‘좋아요’가 많이 찍혀있었기 때문입니다.

응? sudo 쓰지 말라고?

sudo를 통해 문제를 해결했지만, 올바른 해결책인가 싶은 느낌이 들기 시작했습니다. 그래서 디버깅을 시작해보았습니다. 가장 먼저, PermissionError가 왜 발생하는지 살펴보는 것으로 시작했습니다.

문제: admin은 /usr/local/…에 파일을 쓸 권리가 없다.

pip3 install의 default 설치 경로는 다음과 같습니다.

/usr/local/bin/python3.6

문제는, 해당 경로에 파일을 쓰거나(write) 변경할(edit) 권리(privilege)가 저에게는 없다는 점입니다. 이 때의 저는 administrator(이하 admin으로 쓰겠습니다)입니다.

admin이 무엇이고, 왜 일반 admin에게는 읽고 변경할 권리가 없는 지에 대해서는 잠시 뛰어 넘어가도록 하겠습니다.

중요한 사실은, 저에게는 /usr/local/ 경로를 비롯해 하위 경로에 대한 write/edit 권리가 없다는 점입니다. 권리가 없는 자에게는 허락(Permission)도 없습니다.

즉, pip3가 admin에게 허락되지 않은 경로에 패키지를 쓰려고 했기 때문에, 시스템은 PermissionError를 뱉어냈습니다.

퍼미션 에러가 난 이유를 확인했으니, sudo가 왜 이 에러를 해결할 수 있는지 알 수 있을 것입니다. 적어도 sudo가 무엇의 약자인지 알고 계신 분들은 말이지요.

미봉책: sudo는 /usr/local/…에 대한 write + edit 권한을 얻는 키워드

sudo는 Super User Do의 약자로 Linux 명령어입니다. 다음의 뜻을 가지고 있습니다.

“시스템아. 내(administrator)가 슈퍼 유저 특권을 가지고 있다고 생각하렴!”

이 sudo 명령어를 통해, /usr/local/… 에 대한 write/edit 권한을 찾을 수 있습니다.

즉, sudo pip3는 현 admin에게 허락되지 않은 경로에 패키지를 쓰는 것을 허용했고, 저는 permissionError를 회피할 수 있었습니다.

이제 sudo를 쓰면 안되는 이유도 찾아볼 힘이 생겼습니다.

미봉책인 이유: 왜 sudo는 쓰면 안될까?

.

첫 번째 이유는, 원리적으로 하면 안되는 것을 할 이유는 없기 때문입니다. 선현 프로그래머들은 파일 권한 시스템을 만들어서, 시스템의 계층 구조를 합리적으로 만들어 두었습니다. 계층상 상위에 속하는 파일들이 지워지거나 하면 문제가 되기 때문에, 시스템 안정성을 위해 몇몇 경로에는 일반 권한으로는 쓸 수도 지울 수도 없게 만들었습니다. sudo는 시스템 안정을 위해 보호해둘 목적으로 접근 금지한 영역에 숨어 들어가는 키워드입니다. 들어가지 말라는 곳에 함부로 들어갔다가 시스템 전부가 망가지면, 누가 책임집니까? 심지어 sudo 안쓰고도 패키지 관리할 수 있는 대안도 있는데, 굳이 sudo를 쓰면서 권한 시스템을 망칠 필요는 없다고 봅니다. 해서도 안되구요.

.

두 번째 이유는, sudo pip install을 함부로 쓰면, 해킹에 노출되기 때문입니다. 이것은 다소간 첫번째 이유와 이어집니다. sudo pip을 실행한다는 것은, setup.py 파일을 root directory의 강력한 권한(privilege)을 바탕으로 무조건 실행하는 것입니다. 어떤 해커가 setup.py 파일 내에 독성코드를 숨겨놓았다고 해봅시다. 그러면, root system 자체가 무너질 수 있습니다.

해결책: 허락된 경로에 패키지 설치하기

허락되지 않은 경로에 함부로 접근하는 것이 문제라면, 허락된 경로에만 접근하는 것이 해결책이 될 것입니다. 대안은 크게 2가지가 있습니다.

대안 1. 로컬 admin home 경로에 패키지 설치하기

admin에게 허락된 경로에 설치하면 됩니다. 방법은 다음과 같습니다.

pip3 install Pillow --user

현 admin 내부 경로에 설치하는 것입니다. 그러면 설치 경로는 다음과 같습니다.

~/Library/Python/3.6/lib/python/site-packages

참고로, ~/ 는 admin의 home 경로를 지칭합니다.

대안 1의 단점

하지만, 대안 1은 버저닝에 대한 고려가 없습니다. 예를 들어서, 프로젝트_1.py 에서는 pillow version을 1로 해야 하고, 프로젝트_2.py에서는 pillow version을 2로 해야한다고 해봅시다. 즉, 서로 다른 버전을 동시에 활용해야 하는 경우에 우리는 어떻게 대안을 확보할 수 있을까요?

이 질문에 대한 대답이 대안 2 입니다.

대안 2. Virtualenv로 가상 환경에 패키지 설치하기

대안 2 역시 기본적으로, admin에게 허락된 경로에 설치가 됩니다. 대안 1에 비했을 때, 패키지 버전 관리가 편하다는 점에서 장점을 가지고 있습니다. 제가 원했던 Pillow 패키지를 설치에 앞서서 몇 가지 절차가 있습니다. 절차는 다음과 같습니다.

(1) 가상환경을 다룰 수 있는 라이브러리 Virtualenv를 설치합니다.

sudo pip install virtualenv

앞에서는 쓰지 말라고 했던 sudo를 여기서 썼습니다. 물론 원리적으로 생각했을 때에는 sudo를 쓰지 않고, --user를 활용하는 것이 좋을 것입니다. 하지만, virtualenv 같은 패키지는 admin에 무관하게 활용도가 높을 것이라는 판단에 sudo 명령어를 입력하고 root directory에 설치했습니다.

(2) 가상환경을 하나 구성합니다. 이름은 마음대로 설정하면 됩니다. 저는 제 블로그명인 chullin으로 하겠습니다.

virtualenv chullin

그러면, admin의 home directory에 chullin이라는 이름의 디렉토리가 만들어집니다. 다음과 같이 확인해 볼 수 있습니다.

terminal에서 cd를 입력하면, home directory로 이동합니다. 이후, ls를 입력하면, 해당 home directory의 파일들을 확인할 수 있습니다. 저는 chullin으로 가상환경 이름을 설정했기 때문에, 제 admin의 home directory에 chullin이라는 폴더가 형성된 것을 확인할 수 있었습니다.

(3) 가상환경을 활성화(activate)합니다.

source 가상환경이름/bin/activate

저의 경우 아래와 같이 입력했습니다.

source chullin/bin/activate

(4)가상 환경에 원하는 패키지를 설치합니다.

pip install Pillow

그러면, 이제 해당 환경에 패키지가 설치되었음을 확인할 차례입니다. 확인은 chullin/lib/python3.6/ 디렉토리에서 할 수 있습니다.

(5) 가상 환경을 비활성화합니다.

필수적인 절차는 아니지만, 킬 줄 알면 끌 줄도 알아야 할 것입니다.

deactivate

이러면, 환경이 꺼집니다. 이로써, 절차 설명은 끝났습니다. 그 외의 구체적인 사항은 구글링해보시면 됩니다만, 이 정도만 알아도 충분히 유용하게 활용할 수 있습니다.

이제 Pillow 패키지를 써야하는 프로젝트가 생길 때마다, Pillow 패키지가 담겨있는 chullin 가상환경을 (3) 처럼 활성화하고, 해당 가상환경 위에서 파이썬 파일을 돌리면 됩니다. 다 돌렸으면, (5) 처럼 가상환경을 비활성화 하구요.

새로운 패키지를 깔아야 한다면, (3)처럼 활성화 하고, (4)처럼 패키지 설치를 하시면 됩니다. 패키지를 다 깔았으면, (5)처럼 가상환경을 비활성화 하구요.

대안 1 단점(버저닝 문제)을 가상환경(대안 2)으로 해결하기

문제상황은 앞과 마찬가지로, 프로젝트_1.py 에서는 pillow version을 1로 해야 하고, 프로젝트_2.py에서는 pillow version을 2로 해야한다고 해봅시다

가상환경 설치는 대안 1의 단점을 쉽게 해결해 줍니다. chullin_1 이라는 가상 환경에는 pillow version 1을 설치하고, chullin_2이라는 가상환경에는 pillow version 2를 설치하는 식으로요.

chullin_1 가상환경을 활성화하고, 프로젝트_1.py를 실행하고, 다 끝났으면 해당 환경을 비활성화한 후, chullin_2 가상환경을 활성화해 프로젝트_2.py를 실행하는 것이지요.

애초에 왜 pip install은 root directory를 디폴트로 설정했을까?

이 즈음되면, 왜 pip 개발자가 특권이 필요한 경로를 디폴트 경로로 설정했는지 궁금해질 참입니다. 애초에 특권이 필요하지 않은, 일개 admin 입장에서 권한이 허락된 곳에 설치하도록 디폴트 설치 경로가 설정되었다면 더욱 좋았을 텐데 말입니다.

그러면, 수많은 개발자들이 sudo를 피하려고 virtualenv를 설치하려는 수고를 덜 수 있을 것입니다. 혹은 sudo를 피하려고 pip install <package name>뒤에 --user 를 붙이는 수고를 덜 수 있을 것입니다.

다행히도, pip 개발자들도 이에 촉을 세우고 있는 듯 싶습니다.

pip Documentation 6페이지 주석에 따르면,

The pip developers are considering making — user the default for all installs, including get-pip.py installs of pip, but at this time, — user installs for pip itself, should not be considered to be fully tested or endorsed. For discussion, see Issue 1668.

pip 개발자들의 2018년 6월 공식 개발백서(링크) 6 페이지에 따르면, — user를 디폴트로 설정할 계획에 있다고 합니다. 즉, 제가 앞서서 설명한 대안 1을 디폴트로 해두자는 계획을 갖고 있는 것이지요. 구체적인 논의는 여기서 확인해보시면 될 듯 싶습니다. 적극적 대응이 멋있지요.ㅎㅎ.

TL; DR

  • pip 으로 패키지 설치할 때, sudo는 위험하니 절대 쓰지 맙시다.
  • 대신 가상환경 패키지 매니저를 설치하고 가상환경을 활용합시다.
  • pip 개발자도, 특권이 필요한 경로를 디폴트 경로로 설정한 것에 대해후회한다고 합니다.

그럼 이만 안녕히 계세요. 개발자 chullin이었습니다. 궁금하신 점들과 어려운 내용들은 댓글로 해결해주시면 좋겠습니다. 도움이 되신 분들로부터의 Clap은 큰 힘이 됩니다!

짧은 정보

  • pipPython Package Index (PyPI)라는 저장소로부터 파이썬 패키지를 받아 설치하는 패키지 매니징 툴입니다. PyPI은 파이썬 오픈소스 패키지 저장소입니다. easy_install도 패키지 매니징 툴이죠.
  • 개발자들이 자주 활용하는 가상환경 관리 툴로, virtualenv 뿐만 아니라 conda도 있습니다. 혹은 pyenv도 있습니다.
  • superuser 권한을 GUI로 이해할 수 있는 방법도 있네요. 이 링크 참조 부탁드립니다.

--

--