【发布时间】: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
是否可以在使用通过 shebang 调用的 nix-shell 时设置环境变量?例如,我正在使用
#! /usr/bin/env nix-shell
#! nix-shell -i runghc --pure
并想设置一个环境变量,如FOO=bar。请注意,FOO 不一定由周围环境定义。因此--keep FOO 不是一个选项。
【问题讨论】:
标签: nix
您似乎正在使用随附的 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 的情况下如何让nix-shell '解释器' 做到这一点。在这种情况下,您可以求助于在脚本开头或main 开头设置环境变量。如果你需要在真正的解释器运行之前设置一个变量,shell.nix是目前唯一的选择。
shell.nix :-) 感谢您指出!
是的,使用带有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 字符串中。
#! /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 行。似乎没有办法将它分成几行。
也许可以一个接一个地组合2个语言块,并在shebang行中以combining bash and haskell的方式编写一些生成器脚本。
shell.nix file【讨论】: