VPN 관리 명령이 시작될 때 트레이스백이 나타나면, 첫 본능은 다른 Python을 설치하거나 시스템 기본값을 다른 곳으로 돌리는 쪽으로 달려갑니다. 그 본능은 서로 아무 관련이 없는 두 런타임을 섞습니다. 하나는 운영체제와 그 패키지 도구에 속하고, 다른 하나는 여러분이 만드는 프로젝트에 속합니다. 두 번째를 만족시키려고 첫 번째를 바꾸는 것이 바로 작동하던 데스크톱이 패키지 관리자를 잃는 방식입니다.

비교할 가치가 있는 것은 실제로 실패한 구성 요소와 여러분이 바꿀 권한이 있는 런타임 사이입니다. 둘은 거의 결코 같은 대상이 아닙니다.

하나처럼 보이는 두 가지 Python 질문

첫 번째 질문은 트레이스백을 출력한 프로그램을 어느 인터프리터가 실행했는가입니다. 두 번째는 우리 프로젝트가 어느 인터프리터를 써야 하는가입니다. 터미널에서는 둘 다 python3 를 입력해 답하므로 똑같아 보이지만, 소유자도 업그레이드 경로도 영향 범위도 다릅니다.

시스템 도구는 배포판이 함께 제공한 인터프리터와, 그 인터프리터의 ABI에 맞춰 빌드된 컴파일된 모듈에 묶여 있습니다. 프로젝트는 여러분이 그것을 위해 만든 환경에 묶여 있습니다. 시스템 기본값을 옮기면 첫 번째가 기계의 모든 도구에 대해 한 번에 바뀌고, 환경을 만들면 두 번째가 디렉터리 하나에 대해 바뀝니다.

그 행동 중 일 분 안에 되돌릴 수 있는 것은 하나뿐입니다. 그것은 첫 번째가 아닙니다.

어느 구성 요소가 오류를 만들었나

다른 무엇을 읽기 전에 트레이스백의 첫 줄과 그것을 만들어 낸 실행 파일을 읽으세요. 명령줄 프런트엔드, 권한 있는 서비스, API 바인딩은 별개의 조각이며, 그중 일부만 Python입니다.

command -v openvpn3
head -n 1 "$(command -v openvpn3)"
dpkg -S "$(command -v openvpn3)" 2>/dev/null
systemctl status openvpn3-service-client --no-pager

스크립트의 첫 줄은 사용할 인터프리터를 지정하며, 트레이스백은 바로 그 인터프리터에서 나온 것입니다. 패키지 조회는 그 파일의 소유자가 누구인지 알려 주고, 그것이 누가 파일을 바꿀 수 있는지를 결정합니다. 서비스 상태는 전혀 다른 질문에 답합니다: 실제로 세션을 여는 권한 있는 백엔드가 돌고 있는지 여부입니다.

모듈 가져오기 오류, D-Bus 활성화 거부, 거부된 자격 증명은 서로 다른 세 단계입니다. 가져오기 오류는 세션이 존재하기 전에 일어나므로 VPN 설정을 아무리 바꿔도 고쳐지지 않고, 서비스가 정상이어도 고쳐지지 않습니다. 메시지를 그 세 단계 중 하나로 분류하는 것이 실제 첫 단계입니다.

프로젝트 환경이 고칠 수 있는 것과 없는 것

프로젝트 환경은 프로젝트 문제를 풉니다: 한 애플리케이션에 필요한 정확한 라이브러리 버전을 다른 모든 것과 분리해 제공합니다. 그것은 정말 유용하며, 실패하는 프로그램이 여러분의 스크립트일 때는 올바른 도구입니다.

uv run --python 3.11 app.py
python3 -c 'import openvpn3; print(openvpn3.__file__)'

두 번째 명령은 주어진 인터프리터가 바인딩의 어느 사본을 보는지 보여 주며, 빠진 패키지와 가려진 패키지를 구별하는 가장 빠른 방법입니다. 실패하는 스크립트가 쓰는 인터프리터로 실행하고, 우연히 작동하는 다른 인터프리터로 실행하지 마세요.

프로젝트 환경이 할 수 없는 일은 배포판이 패키지한 프런트엔드를 고치는 것입니다. 그 프로그램의 의존성은 패키지 관리자가 고른 인터프리터에 맞춰 빌드되었고, 프로젝트 환경 안에서 실행하면 실패하거나 아무도 지원하지 않는 혼합물이 됩니다. 환경 변수로 경로를 주입하는 것은 단계만 늘어난 같은 실수입니다: 도구가 불러오는 것은 바꿨지만 무엇을 대상으로 시험했는지는 바꾸지 않았습니다. 그 맞바꿈은 다음 가져오기에 부딪힐 때까지만 수정처럼 보입니다.

시스템 인터프리터를 바꾸는 것이 함정인 이유

기본 인터프리터를 바꾸는 것은 한 명령으로 트레이스백이 고쳐지는 것처럼 보여 매력적입니다. 그것은 또한 호스트의 모든 패키지된 Python 도구가 전제한 가정을 깨뜨리고, 고장은 나중에 무관한 곳에서 나타납니다.

대안 선택 메커니즘은 동등한 구현 사이를 전환하도록 설계된 것이지, 더 오래된 컴파일된 모듈 아래에 더 새로운 언어를 설치하기 위한 것이 아닙니다. 컴파일된 확장은 특정 ABI에 맞춰 빌드되므로, 어제 가져온 모듈이 패키지를 하나도 제거하지 않았는데 오늘 로드되지 않을 수 있습니다.

사람들이 찾는 조언에는 이름에 관한 함정도 있습니다. 버전이 없는 python 명령은 배포판과 환경을 넘어 하나의 보편적 의미를 갖지 않으며, 특정 주 버전의 고정된 동의어로 다루면 그것을 쓴 기계에서만 통하는 수정이 됩니다. 블로그 글의 정책이 아니라 눈앞의 시스템 정책을 읽으세요.

분리된 인수 시험

마지막에 두 가지 시험이 있어야 하고, 하나를 통과한다고 다른 하나에 대해 말할 수 있는 것은 없습니다. 첫째는 지원되는 클라이언트 명령이 그것이 패키지된 인터프리터에서 동작하는 것입니다. 둘째는 권한 있는 서비스가 세션을 열고 터널이 트래픽을 나르는 것입니다.

openvpn3 sessions-list
openvpn3-service-client --help 2>/dev/null | head -n 3
ip -4 addr show tun0

작업하는 동안, 특히 VPN이 유일한 관리 접근을 나르는 경우에는, 기계로 들어가는 독립적인 경로를 유지하세요. 시스템 인터프리터 변경은 바로 그 접근을 중간에 없앨 수 있는 종류의 편집입니다.

실패가 시스템 도구의 누락된 모듈이라면 수정은 지원되는 작업 흐름을 통한 패키지 작업입니다. 실패가 여러분 프로젝트의 버전 충돌이라면 수정은 환경입니다. 그 둘 중에서 고르는 것이 결정의 전부이며, 그것은 어느 프로그램이 트레이스백을 출력했느냐로 정해집니다.

관련 글