[LINUX] Verwalten Sie die Umgebung deklarativ mit Nix und Home-Manager

Wenn Sie den Nix-Paketmanager einbeziehen, möchten Sie auf jeden Fall den Home-Manager einbeziehen. home-manager ist ein Tool zum deklarativen Verwalten der Benutzerumgebung mit nix.

Es ist ein hervorragendes Tool, mit dem Sie verschiedene Benutzereinstellungen deklarativ in einer einzigen Datei verwalten können.

Wenn Sie nur nix und home-manager einsetzen, ist es kein Traum, das Setup mit einem einzigen Befehl abzuschließen, selbst wenn Sie den PC wechseln. (Das habe ich getan, als ich meinen PC bei der Arbeit ausgetauscht habe.)

Weitere Informationen finden Sie unter Home-Manager-Github-Seite oder Handbuch. Wie Sie sehen können, ist es auf Englisch und es ist lang, also fasse ich nur die wichtigsten Punkte für mich zusammen.

Home-Manager-Installation

Sie benötigen Nix Package Manager, um Home-Manager verwenden zu können. Installieren Sie also zuerst Nix.

> curl -L https://nixos.org/nix/install | sh
> nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
> nix-channel --update

Sie können einen Kanal mit nixchannel --add <url> [channel-alias] registrieren. Es ist wie das Registrieren eines Repositorys.

Um den Home-Manager zu installieren, abonnieren Sie zuerst den Home-Manager-Kanal.

> nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
> nix-channel --update

Anschließend können Sie es installieren, indem Sie den folgenden Befehl eingeben.

> nix-shell '<home-manager>' -A install

Paketverwaltung

Um Ihre Benutzerumgebung mit dem Home-Manager einzurichten, erstellen Sie "~ / .config / nixpkgs / home.nix".

In den folgenden Einstellungen werden beispielsweise git und GNU / hello installiert.

nix:.config/nixpkgs/home.nix


{ pkgs, ... }:
{
    #Das ist Zuhause-Wird automatisch eingegeben, wenn der Manager installiert ist
    programs.home-manager.enable = true;
    home.username = "hnakano";
    home.stateVersion = "20.09";

    #Deklarieren Sie das zu installierende Paket hier
    home.packages = [
        pkgs.git
        pkgs.hello
    ];
}

Geben Sie dann den folgenden Befehl ein, um die Einstellungen wiederzugeben.

> home-manager switch

Diese Konfigurationsdatei ist in einer eigenen Sprache namens Nix-Ausdruck geschrieben. Um ehrlich zu sein, ist es fast wie bei json, so dass Sie sich nicht zu viele Gedanken über die Grammatik machen müssen, aber ich werde die Mindestgrammatik für diejenigen erklären, die sich darum kümmern.

Mindestgrammatik für die Verwendung von Home-Manager

repl Es gibt einen Nix-Ausdruck repl. Sie können repl eingeben, indem Sie in der Befehlszeile "nix repl" eingeben.

> nix repl
Welcome to Nix version 2.3.7. Type :? for help.

nix-repl>

Geben Sie :? Ein, um Hilfe mit dem Befehl repl zu erhalten. Sie können repl mit : q beenden.

Grundtyp

Es gibt numerische, boolesche und Zeichenfolgentypen. Die Zeichenfolgenverkettung ist "+".

nix-repl> 1 #interger
1

nix-repl> 3.14 #float
3.14

nix-repl> true #boolean
true

nix-repl> "hogehoge" #string
"hogehoge"

nix-repl> "hoge" + "fuga" #string concatenate
"hogefuga"

let ... in

Verwenden Sie let ... in, um einer Variablen einen Wert zuzuweisen. Achten Sie auf die Position des Semikolons.

nix-repl> let x = 1; y = 2; z = x + y; in z * 2
6

Sie können Werte nur in repl zuweisen, ohne let ... in zu verwenden. Beachten Sie jedoch, dass ein normaler Nix-Ausdruck nicht auf diese Weise geschrieben werden kann.

nix-repl> x = 3

nix-repl> y = 4

nix-repl> x + y
7

List

Die Liste ist "[a b c]". Elementtrennzeichen sind Leerzeichen halber Breite oder Zeilenumbrüche. Übrigens müssen die Typen nicht übereinstimmen **

nix-repl> [ 1 "hoge" true ]
[ 1 "hoge" true ]

nix-repl> [
            1
            2
            3
          ]
[ 1 2 3 ]

Verwenden Sie die integrierte Funktion builtins.elemAt, um auf die Elemente der Liste zuzugreifen. Zum Anwenden der Funktion sind keine Klammern erforderlich.

nix-repl> x = [ 1 2 3 ]

nix-repl> builtins.elemAt x 0
1

nix-repl> builtins.elemAt x 1
2

Funktion

Nix-Funktionen haben die Form "arg: body". Die linke Seite des Doppelpunkts ist das Argument. Die Funktion mit zwei Argumenten lautet "arg1: arg2: body".

nix-repl> hello =  x: "hello, " + x  

nix-repl> hello "world"
"hello, world"

Grundsätzlich kann Nix nur anonyme Funktionen erstellen.

nix-repl> x: y: x + y
«lambda @ (string):1:1»

Wenn Sie die Funktion benennen möchten, verwenden Sie den Ausdruck let

nix-repl> let
            add = x: y: x + y;
            add2 = add 2; #Kann teilweise angewendet werden
          in
          add2 3 #Gleich wie add 2 3
5

Attribute set

Ein Attributsatz ist ein Paar von Schlüssel = Wert in mittleren Klammern in Form von "{Schlüssel1 = Wert1; Schlüssel2 = Wert2;}". Am Ende des Paares key = value; ist immer ein Semikolon erforderlich.

Sie können auf den Wert in der Form "x.key1" zugreifen.

nix-repl> let
            x = {     
              hoge = "hoge";
              fuga = "fuga";
            };
          in x.hoge
"hoge"
Eine Funktion, die einen Attributsatz als Argument verwendet

Funktionen, die einen Attributsatz als Argument verwenden, können normalerweise in der Form "arg: body" definiert werden.

nix-repl> let
            f = x: x.hoge + x.fuga;
          in f { hoge = "hoge"; fuga = "fuga"; }
"hogefuga"

Es kann jedoch auch in der Form "{key1, key2}: body" definiert werden. In diesem Formular tritt ein Fehler auf, wenn der Name des Argumentschlüssels nicht genau übereinstimmt. Sie können diesen Fehler vermeiden, indem Sie "..." in das Argument einfügen, z. B. "{key, key2, ...}: body".

nix-repl> f = { hoge, fuga }: hoge + fuga

nix-repl> let x = { hoge = "hoge"; fuga = "fuga"; }; in f x
"hogefuga"

nix-repl> let y = { hoge = 3; fuga = 4; piyo = true; }; in f y
error: anonymous function at (string):1:2 called with unexpected argument 'piyo', at (string):1:50

nix-repl> g = { hoge, ... }: "hello, " + hoge

nix-repl> let y = { hoge = "world"; fuga = 4; piyo = true; }; in g y
"hello, world"

Andere

Grammatikreferenz für Nix-Ausdruck

Lesen Sie die Konfigurationsdatei

Lesen wir zuerst die zuerst definierte Einstellungsdatei.

nix:./config/nixpkgs/home.nix


{ pkgs, ... }:
{
    #Das ist Zuhause-Wird automatisch eingegeben, wenn der Manager installiert ist
    programs.home-manager.enable = true;
    home.username = "hnakano";
    home.stateVersion = "20.09";

    #Deklarieren Sie das Paket hier
    home.packages = [
        pkgs.git
        pkgs.hello
    ];
}

Zunächst können wir sehen, dass dieser Ausdruck eine Funktion ist, die ein Attribut mit dem Schlüssel pkgs verwendet. pkgs enthält normalerweise <nixpkgs>, dh die Nix-Paketsammlung.

{key1.key2 = value;} ist der Syntaxzucker für den verschachtelten Attributsatz, der für {key1 = {key2 = value;};} steht.

Ohne Syntaxzucker würde diese Konfigurationsdatei folgendermaßen aussehen:

{ pkgs, ... }:
{
    programs = {
        home-manager = {
            enable = true;
        };
    };

    home = {
        username = "hnakano";
        stateVersion = "20.09";
        packages = [
            pkgs.git;
            pkgs.hello;
        ];
    };
}

Das heißt, diese Funktion verwendet einen Attributsatz von {pkgs = ..; ...} als Argument. Es ist eine Funktion, die einen Attributsatz von {programme = {...}; home = {...};} zurückgibt.

Der Befehl home-manager wertet diesen Rückgabewert aus und spiegelt die Einstellungen in der Benutzerumgebung wider.

Andere Einstellungselemente

Ich werde verschiedene Einstellungen mit Home-Manager versuchen. Informationen zu den Inhalten, die in Home-Manager festgelegt werden können, finden Sie im Home-Manager-Handbuch.

nix:.config/nixpkgs/home.nix


{
  home.packages = with pkgs; [ nixfmt exa bat source-han-code-jp ];

  programs.git = {
    enable = true;
    userName = "hnakano863";
    userEmail = "[email protected]";
    extraConfig.pull.rebase = false;
  };

  fonts.fontconfig.enable = true;

  programs.bash = {
    enable = true;
    profileExtra = ''
      export XDG_DATA_DIRS=$HOME/.nix-profile/share''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS
      export LIBGL_ALWAYS_INDIRECT=1
      export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
      if [ -e $HOME/.nix-profile/etc/profile.d/nix.sh ]; then
          . $HOME/.nix-profile/etc/profile.d/nix.sh;
      fi
    '';
    initExtra = ''
      if [ -z $IN_NIX_SHELL ]; then exec fish fi
    '';
    shellAliases = {
      ls = "exa";
      cat = "bat";
    };
  };

  programs.fish = {
    enable = true;
    interactiveShellInit = ''
      set -gx fish_user_paths $HOME/go/bin $HOME/.local/bin
    '';
  };
      
  programs.tmux = {
    enable = true;
    clock24 = true;
    keyMode = "vi";
    shortcut = "a";
    terminal = "screen-256color";
  };
}

Es gibt einige grammatikalische Elemente, die ich nicht erklärt habe, deshalb werde ich sie erklären.

Erstens gibt es in home.packages die Form mit pkgs; [...]. Dies ist eine Syntax, um das Schreiben von "pkgs." wie "[pkgs.nixfmt pkgs.exa ...]" zu vermeiden.

Als nächstes folgt die Zeichenfolge in zwei einfachen Anführungszeichen, die in programs.bash.profile Extra usw. angezeigt wird. Dies ist eine Zeichenfolge vom Typ eingerückte Zeichenfolge.

Einzug wird in der eingerückten Zeichenfolge ignoriert, was zum Schreiben von Shell-Skripten nützlich ist. Tatsächlich spiegelt sich programs.bash.profile Extra in ~ / .profile wider.

Wenn Sie schließlich "programs.bash.enable = true;" haben, wird durch Ausführen von "home-manager switch" versucht, "~ / .profile", "~ / .bashrc" usw. zu ersetzen. Wenn zu diesem Zeitpunkt bereits eine vorhandene Konfigurationsdatei wie "~ / .bashrc" in der Benutzerumgebung vorhanden ist, schlägt der Befehl "home-manager" mit dem Fehler "Ich habe eine Konfigurationsdatei" fehl. Um dies zu vermeiden, speichern Sie die vorhandene Datei im Voraus mit mv ~ / .bashrc ~ / .bashrc.bk.

Recommended Posts

Verwalten Sie die Umgebung deklarativ mit Nix und Home-Manager
Verwalten Sie Python-Laufzeitpakete und Entwicklungsumgebungspakete mit Poetry
Verwalten Sie die Python-Umgebung mit virtualenv
Verwalten Sie Ihre Daten mit AWS RDS
Erstellen einer Umgebung mit pyenv und pyenv-virtualenv
Erstellen Sie mit Anaconda und PyCharm eine Python-Umgebung auf Ihrem Mac
Bereinigen Sie die Python-Umgebung mit Pythonz und virtualenv
Aufbau einer MacOS 10.11-Umgebung: Powerline mit Anaconda und Dein.vim
Erstellen einer Python-Umgebung mit virtualenv und direnv
Django: User Agent aufzeichnen und mit Admin verwalten
Verwalten Sie die Python-Umgebung mit mehreren Versionen mit Pythonz, virtualenv
Verwalten Sie Statusübergänge und kommunizieren Sie mit intelligenten Zählern
Erstellen Sie eine virtuelle Umgebung mit pyenv und venv
Erstellen Sie eine virtuelle Python-Umgebung mit virtualenv und virtualenvwrapper
Erstellen Sie eine virtuelle Python-Umgebung mit virtualenv und virtualenvwrapper
Verwalten Sie die Aufbewahrung von Amazon CloudWatch-Protokollgruppen mit AWS Lambda
Installieren Sie Ubuntu 20.04 mit GUI und bereiten Sie die Entwicklungsumgebung vor
Automatisieren Sie Chrome mit Python und Selen auf Ihrem Chromebook
So richten Sie die Cython-Umgebung ein und kompilieren sie
Erstellen einer numerischen Berechnungsumgebung mit pyenv und miniconda3