【问题标题】:Setting environment variables in nix via a shebang通过shebang在nix中设置环境变量
【发布时间】:2020-06-07 14:29:40
【问题描述】:

是否可以在使用通过 shebang 调用的 nix-shell 时设置环境变量?例如,我正在使用

#! /usr/bin/env nix-shell
#! nix-shell -i runghc --pure

并想设置一个环境变量,如FOO=bar。请注意,FOO 不一定由周围环境定义。因此--keep FOO 不是一个选项。

【问题讨论】:

    标签: nix


    【解决方案1】:

    您似乎正在使用随附的 shell.nix 文件。您可以在那里简单地将环境变量定义为派生属性。

    shell.nix

    pkgs.mkShell {
      buildInputs = [ pkgs.ghc ];
      shellHook = ''
        VIA_SHELL_HOOK=it\ works   # no it doesn't
      '';
      VIA_DRV_ATTR = "working";
    }
    
    

    示例可执行脚本

    #!/usr/bin/env nix-shell
    #!nix-shell -i runghc --pure
    
    import System.Environment(getEnv)
    
    main = do
      getEnv "VIA_DRV_ATTR" >>= print
      getEnv "VIA_SHELL_HOOK" >>= print
    

    输出:

    "working"
    hello: VIA_SHELL_HOOK: getEnv: does not exist (no environment variable)
    

    (Nix 2.3.4,Nixpkgs 20.03)

    【讨论】:

    • 我没有使用附带的 shell.nix 文件。但是,我什至不知道在使用 shebang 时这是可能的。所以你的解决方案对我来说非常有效。谢谢!
    • 我不知道在没有shell.nix 的情况下如何让nix-shell '解释器' 做到这一点。在这种情况下,您可以求助于在脚本开头或main 开头设置环境变量。如果你需要在真正的解释器运行之前设置一个变量,shell.nix是目前唯一的选择。
    • 我已经在尝试shell.nix :-) 感谢您指出!
    【解决方案2】:

    是的,使用带有shebang的nix时可以设置环境变量。

    使用 bash shebang 将 nix 作为单个文件中的主要语言

    #! /usr/bin/env -S bash -c 'nix-shell --pure $0'
    
    with import <nixpkgs> {};
    let
      haskellCode = ''
        import System.Environment (getEnv)
    
        main = do
          getEnv "VIA_DRV_ATTR" >>= print
          getEnv "VIA_SHELL_HOOK" >>= print
      '';
    in
    mkShell {
      buildInputs = [ ghc ];
      shellHook = ''
        export VIA_SHELL_HOOK="VIA_SHELL_HOOK works"
        exec runghc <<< '${haskellCode}'
      '';
      VIA_DRV_ATTR = "VIA_DRV_ATTR works";
    }
    
    $ ./test.nix 
    "VIA_DRV_ATTR works"
    "VIA_SHELL_HOOK works
    

    缺点是 haskell 代码嵌入在 nix 字符串中。

    haskell(或任何其他)作为主要语言使用 nix shebang 在单个文件中

    #! /usr/bin/env nix-shell
    #! nix-shell -i runghc --pure -E "with import <nixpkgs> {}; mkShell { buildInputs = [ ghc ]; VIA_DRV_ATTR = \"VIA_DRV_ATTR works\"; shellHook = ''export VIA_SHELL_HOOK=\"VIA_SHELL_HOOK works\"''; }"
    
    import System.Environment (getEnv)
    
    main = do
      getEnv "VIA_DRV_ATTR" >>= print
      getEnv "VIA_SHELL_HOOK" >>= print
    
    $ ./test.hs
    "VIA_DRV_ATTR works"
    "VIA_SHELL_HOOK works"
    

    缺点是带有转义引号的冗长的 shebang nix-shell 行。似乎没有办法将它分成几行。

    nix 和另一种语言在一个文件中使用 shebang?

    也许可以一个接一个地组合2个语言块,并在shebang行中以combining bash and haskell的方式编写一些生成器脚本。

    haskell (or any other) in a file with nix shebang with accompanying shell.nix file

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 2013-01-09
      • 2016-01-23
      • 1970-01-01
      相关资源
      最近更新 更多