Skip to content

프로젝트에서 명령어 실행하기

프로젝트를 작업할 때, .venv 가상 환경에 설치된다. 이 환경은 기본적으로 현재 셸과 격리되어 있기 때문에, python -c "import example"과 같이 프로젝트가 필요한 명령어는 실패한다. 대신 uv run을 사용해 프로젝트 환경에서 명령어를 실행한다:

$ uv run python -c "import example"

run을 사용하면, uv는 주어진 명령어를 실행하기 전에 프로젝트 환경이 최신 상태인지 확인한다.

주어진 명령어는 프로젝트 환경에서 제공되거나 외부에 존재할 수 있다. 예를 들어:

$ # 프로젝트가 `example-cli`를 제공한다고 가정
$ uv run example-cli foo

$ # 프로젝트가 필요로 하는 `bash` 스크립트 실행
$ uv run bash scripts/foo.sh

추가 의존성 요청

각 실행마다 추가 의존성이나 다른 버전의 의존성을 요청할 수 있다.

--with 옵션을 사용해 실행 시 의존성을 포함할 수 있다. 예를 들어 httpx의 다른 버전을 요청하려면 다음과 같이 한다:

$ uv run --with httpx==0.26.0 python -c "import httpx; print(httpx.__version__)"
0.26.0
$ uv run --with httpx==0.25.0 python -c "import httpx; print(httpx.__version__)"
0.25.0

요청한 버전은 프로젝트의 요구사항과 관계없이 적용된다. 예를 들어 프로젝트가 httpx==0.24.0을 요구하더라도 위의 결과는 동일하게 출력된다.

스크립트 실행

인라인 메타데이터를 선언한 스크립트는 프로젝트와 격리된 환경에서 자동으로 실행된다. 자세한 내용은 스크립트 가이드를 참고한다.

예를 들어, 다음과 같은 스크립트가 있다고 가정해 보자:

example.py
# /// script
# dependencies = [
#   "httpx",
# ]
# ///

import httpx

resp = httpx.get("https://peps.python.org/api/peps.json")
data = resp.json()
print([(k, v["title"]) for k, v in data.items()][:10])

uv run example.py 명령어를 실행하면, 프로젝트와 격리된 상태에서 주어진 의존성만으로 스크립트가 실행된다.

시그널 처리

uv는 실패 시 더 나은 에러 메시지를 제공하기 위해 프로세스 제어권을 생성된 커맨드에 넘기지 않는다. 따라서 uv는 요청된 커맨드가 실행되는 자식 프로세스로 일부 시그널을 전달할 책임이 있다.

Unix 시스템에서 uv는 SIGINT와 SIGTERM을 자식 프로세스로 전달한다. 쉘은 Ctrl-C를 누를 때 포그라운드 프로세스 그룹에 SIGINT를 보내기 때문에, uv는 SIGINT가 여러 번 발생하거나 자식 프로세스 그룹이 uv와 다른 경우에만 자식 프로세스로 SIGINT를 전달한다.

Windows에서는 이러한 개념이 적용되지 않으며, uv는 Ctrl-C 이벤트를 무시하고 자식 프로세스가 깔끔하게 종료할 수 있도록 처리를 미룬다.