【问题标题】:Running shell commands from Haskell in NixOS在 NixOS 中从 Haskell 运行 shell 命令
【发布时间】:2018-06-19 08:26:30
【问题描述】:

我是 NixOS 的新手,正在尝试使用以下函数从 Haskell 程序调用 emacs:

ediff :: String -> String -> String -> IO ()
ediff testName a b = do
  a' <- writeSystemTempFile (testName ++ ".expected") a
  b' <- writeSystemTempFile (testName ++ ".received") b
  let quote s = "\"" ++ s ++ "\""
  callCommand $ "emacs --eval \'(ediff-files " ++ quote a' ++ quote b' ++ ")\'"

当我运行使用stack test 调用此命令的程序时,我得到以下结果(穿插单元测试结果):

/bin/sh: emacs: command not found
Exception: callCommand: emacs --eval '(ediff-files "/run/user/1000/ast1780695788709393584.expected" "/run/user/1000/ast4917054031918502651.received")'

当我从我的 shell 运行无法在上面运行的命令时,它可以完美运行。如何在 NixOS 中从 Haskell 运行进程,就像我直接调用它们一样,以便它们可以访问与我的用户相同的命令和配置?

【问题讨论】:

    标签: haskell nixos


    【解决方案1】:

    你的 shell 和 callCommand 都使用 PATH 环境变量,所以看起来堆栈正在改变它。事实证明,stack 默认使用纯 nix shell,但您还想访问您的用户环境,即“不纯”。

    引用stack documenation

    默认情况下,stack 将在纯 Nix 构建环境(或 shell)中运行构建,这意味着如果您没有在包中指定所有依赖项,构建应该会失败:stack.yaml 文件的部分,甚至如果这些依赖项安装在系统的其他位置。此行为强制构建环境的完整描述以促进可重复性。要覆盖此行为,请将 pure: false 添加到您的 stack.yaml 或将 --no-nix-pure 选项传递给命令行。

    另一种解决方案是将 Emacs 添加到 nix.dependencies 中的 stack.yaml(感谢 @chepner)。它的好处是,当开发人员运行测试时,某些版本的 Emacs 将始终可用,但 Emacs 可能不是他们想要使用的 Emacs。你可以使用~/.config/nixpkgs/config.nix 之类的东西来解决这个问题,除非他们已经在其他地方配置了他们的 Emacs,比如系统配置或者家庭管理器。我更喜欢简单但不纯的$PATH 解决方案。

    【讨论】:

    • 解决方案是将emacs 添加到依赖列表中,而不是使用不纯的环境,对吧?
    • 谢谢!我还没有时间使用您的建议,但这非常有用。
    猜你喜欢
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2011-03-03
    • 2011-06-04
    • 2015-07-17
    • 2018-07-30
    • 2011-01-28
    相关资源
    最近更新 更多