如何将环境变量传入通过stack运行的Haskell程序?
解决Stack运行Haskell程序时环境变量无法传递的问题
这个问题其实是Stack的默认行为导致的——为了保证构建和运行环境的可重复性,Stack默认会创建一个干净的隔离环境,只保留少数系统必要或Stack自身的环境变量,大部分用户自定义的环境变量(比如你的FOOBAR)会被过滤掉。下面针对不同场景给出具体的解决方法:
1. 直接用stack runhaskell或stack exec运行程序
如果你只是临时需要传递某个环境变量,可以用Stack的--environment-vars(简写--env)参数指定要保留的变量:
# 传递单个变量 FOOBAR=123 stack runhaskell --env FOOBAR testenv.hs # 传递多个变量,用逗号分隔 FOOBAR=123 BAZ=456 stack exec --env FOOBAR,BAZ testenv
如果需要保留所有用户环境变量(不推荐,会破坏环境的可重复性),可以用--keep-env参数:
FOOBAR=123 stack runhaskell --keep-env testenv.hs
2. 针对Yesod Devel的场景
Yesod Devel底层依赖Stack运行,所以你可以通过--stack-arg参数把环境变量相关的配置传递给Stack:
# 传递单个环境变量给yesod devel FOOBAR=123 yesod devel --stack-arg="--env FOOBAR" # 传递多个变量 FOOBAR=123 BAZ=456 yesod devel --stack-arg="--env FOOBAR,BAZ"
如果希望每次启动Yesod Devel都自动保留这些变量,可以修改项目根目录的stack.yaml,添加environment配置段:
environment: keep: - FOOBAR - BAZ # 可以添加多个需要保留的变量
这样之后再运行yesod devel时,Stack会自动把这些环境变量传递给程序。
补充说明
Stack默认隔离环境的设计是为了避免不同机器、不同用户的环境差异导致构建或运行结果不一致,这也是它能保证可重复性的核心特性之一。所以除非确实需要,尽量不要使用--keep-env保留所有环境变量,而是精准指定需要传递的变量,既能满足需求,又能维持环境的可控性。
内容的提问来源于stack exchange,提问作者chrisleague
相关产品推荐
相关产品推荐

