通过 shebang 在 nix 中设置环境变量
Setting environment variables in nix via a shebang
是否可以在使用通过 shebang 调用的 nix-shell 时设置环境变量?例如,我正在使用
#! /usr/bin/env nix-shell
#! nix-shell -i runghc --pure
并想设置一个环境变量,如 FOO=bar
。注意,FOO
不一定是由周围环境定义的。因此 --keep FOO
不是一个选项。
您似乎在使用随附的 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)
是的,在使用带有 shebang 的 nix 时可以设置环境变量。
nix 作为单个文件中的主要语言 bash shebang
#! /usr/bin/env -S bash -c 'nix-shell --pure [=10=]'
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 行带有转义引号。似乎没有办法将它分成几行。
使用 shebang 在一个文件中同时使用 nix 和另一种语言?
也许可以将2个语言块一个接一个地组合起来,然后按照combining bash and haskell.
的方式在shebang行中编写一些生成器脚本
是否可以在使用通过 shebang 调用的 nix-shell 时设置环境变量?例如,我正在使用
#! /usr/bin/env nix-shell
#! nix-shell -i runghc --pure
并想设置一个环境变量,如 FOO=bar
。注意,FOO
不一定是由周围环境定义的。因此 --keep FOO
不是一个选项。
您似乎在使用随附的 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)
是的,在使用带有 shebang 的 nix 时可以设置环境变量。
nix 作为单个文件中的主要语言 bash shebang
#! /usr/bin/env -S bash -c 'nix-shell --pure [=10=]'
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 行带有转义引号。似乎没有办法将它分成几行。
使用 shebang 在一个文件中同时使用 nix 和另一种语言?
也许可以将2个语言块一个接一个地组合起来,然后按照combining bash and haskell.
的方式在shebang行中编写一些生成器脚本