shell.nix를 사용한 선언적 셸 환경#
- Authors:
Domen Kožar @domenkozar, Zach Mitchell @zmitchell
- Editor:
Valentin Gagarin @fricklerhandwerk
개요#
선언적 셸 환경을 사용하면 다음과 같은 일을 할 수 있습니다:
환경 활성화 시 bash 명령을 자동으로 실행합니다
환경 변수를 자동으로 설정합니다
환경 정의를 버전 관리하에 두고 다른 머신에서 재현합니다
무엇을 배우게 됩니까?#
임시 셸 환경 튜토리얼에서는 nix-shell -p를 사용하여 셸 환경을 명령적으로 만드는 방법을 배웠습니다. 이 방법은 도구를 영구적으로 설치하지 않고 빠르게 사용하고 싶을 때 매우 유용합니다. 또한 이전에 사용한 것과 동일한 환경을 다시 만들기 위해, Git 커밋을 인수로 사용하여 특정 Nixpkgs 리비전으로 해당 명령을 실행하는 방법도 배웠습니다.
이 튜토리얼에서는 Nix 파일에 작성한 선언적 설정으로 재현 가능한 셸 환경을 만드는 방법을 살펴보겠습니다. 이 파일을 누구와도 공유하여 다른 머신에서 동일한 환경을 다시 만들 수 있습니다.
얼마나 걸립니까?#
30분
무엇이 필요합니까?#
Unix 셸에 대한 익숙함
Nix 언어에 대한 기초적인 이해
임시 셸 진입하기#
cowsay와 lolcat을 사용할 수 있는 환경이 필요하다고 가정해 봅시다. 이를 달성하는 가장 간단한 방법은 nix-shell -p 명령을 사용하는 것입니다:
$ nix-shell -p cowsay lolcat
이 명령은 작동하지만 여러 가지 단점이 있습니다:
셸에 진입할 때마다
-p cowsay lolcat을 입력해야 합니다.셸 환경을 더 이상 (편리하게) 사용자 지정할 수 없습니다.
더 나은 해결책은 shell.nix 파일로 셸 환경을 만드는 것입니다.
기본적인 shell.nix 파일#
다음 내용으로 shell.nix라는 파일을 만드십시오:
1let
2 nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
3 pkgs = import nixpkgs { config = {}; overlays = []; };
4in
5
6pkgs.mkShellNoCC {
7 packages = with pkgs; [
8 cowsay
9 lolcat
10 ];
11}
자세한 설명
릴리스 브랜치에 고정된 Nixpkgs 버전을 사용합니다. 임시 셸 환경 튜토리얼을 따라 했고 모든 의존성을 다시 다운로드하고 싶지 않다면, 재현성을 향하여 섹션에서와 정확히 동일한 리비전을 지정하십시오:
1let
2 nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/2a601aafdc5605a5133a2ca506a34a3a73377247";
3 pkgs = import nixpkgs { config = {}; overlays = []; };
4in
전역 설정에 의해 의도치 않게 오버라이드되는 것을 방지하기 위해 config와 overlays를 명시적으로 설정합니다.
mkShellNoCC는 속성 집합을 인수로 받는 함수입니다. 여기서는 pkgs 속성 집합의 두 항목을 담은 목록을 packages 속성으로 전달합니다.
mkShell에 대한 참고 사항
nix-shell과 mkShell은 원래 Make나 GCC 같은 패키지 빌드를 디버깅하는 데 필요한 도구를 담은 셸 환경을 구성하는 방법으로 고안되었습니다. 나중에야 다른 목적의 임시 환경을 만드는 일반적인 방법으로 널리 쓰이게 되었습니다. mkShellNoCC는 이러한 환경을 만들되 컴파일러 툴체인은 포함하지 않는 함수입니다.
패키지를 buildInputs나 nativeBuildInputs 속성에 대신 추가하는 mkShell 또는 mkShellNoCC 예제를 볼 수도 있습니다. mkShellNoCC는 mkDerivation을 감싼 래퍼이므로 buildInputs나 nativeBuildInputs 같은 mkDerivation과 동일한 인자를 받습니다. mkShellNoCC에 전달하는 packages 속성 인자는 단순히 nativeBuildInputs의 별칭입니다.
shell.nix와 같은 디렉터리에서 nix-shell을 실행하여 환경에 진입하십시오:
참고
이 파일에 대해 nix-shell을 처음 실행하면 모든 의존성을 내려받느라 시간이 걸릴 수 있습니다.
$ nix-shell
[nix-shell]$ cowsay hello | lolcat
nix-shell은 기본적으로 현재 디렉터리에서 shell.nix라는 파일을 찾아 이 파일의 Nix 표현식으로부터 셸 환경을 빌드합니다. packages 속성에 정의된 패키지는 $PATH에서 사용할 수 있습니다.
환경 변수#
셸 환경에 진입할 때 특정 환경 변수를 자동으로 내보내고 싶을 수 있습니다.
셸 환경에서 사용할 수 있도록 GREETING을 설정하십시오:
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShellNoCC {
packages = with pkgs; [
cowsay
lolcat
];
+ GREETING = "Hello, Nix!";
}
mkShellNoCC에 전달된 속성 이름 중 달리 예약되지 않았고 문자열로 변환할 수 있는 값을 가진 속성은 모두 환경 변수가 됩니다.
직접 해 보십시오. exit를 입력하거나 Ctrl+D를 눌러 셸을 종료한 다음, nix-shell로 다시 시작하십시오.
[nix-shell]$ echo $GREETING
경고
일부 변수는 위에서 설명한 방식으로 설정할 수 없도록 보호되어 있습니다.
예를 들어, 대부분의 셸에서 셸 프롬프트 형식은 PS1 환경 변수로 설정되지만, nix-shell이 이미 기본값을 설정하므로 인수로 전달한 속성 집합에 설정된 PS1 속성은 무시됩니다.
이렇게 보호된 환경 변수를 오버라이드해야 한다면 다음 절에서 설명하는 대로 shellHook 속성을 사용하십시오.
시작 명령#
대화형 셸 환경에 진입하기 전에 몇 가지 셸 명령을 실행하고 싶을 수 있습니다. 이러한 명령은 mkShellNoCC에 전달하는 shellHook 속성에 넣을 수 있습니다.
알록달록한 인사말을 출력하도록 shellHook을 설정하십시오:
let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShellNoCC {
packages = with pkgs; [
cowsay
lolcat
];
GREETING = "Hello, Nix!";
+
+ shellHook = ''
+ echo $GREETING | cowsay | lolcat
+ '';
}
다시 해 보십시오. exit를 입력하거나 Ctrl+D를 눌러 셸을 종료한 다음, nix-shell로 다시 시작하여 결과를 확인하십시오.
참고 자료#
Nixpkgs 셸 함수 및 유틸리티 문서