【问题标题】:How can I set an environment variable in a cross-platform way?如何以跨平台的方式设置环境变量?
【发布时间】:2012-02-14 10:13:41
【问题描述】:

我可以使用System.Environment.getEnv 轻松读取环境变量。但是,System.Environment 没有任何对应的setEnv 函数(据我所知)。

如何从 Haskell 程序中设置环境变量?我更喜欢跨平台的解决方案。 (所以只执行export VAR=val 或使用System.Posix.Env 并不是我想要的。)

【问题讨论】:

  • 请注意,base 4.7.0 现在有一个setEnv
  • @EmmanuelTouzery:太棒了。你能把它作为提高知名度的答案吗?谢谢。

标签: haskell cross-platform environment-variables


【解决方案1】:

请注意,基础 4.7.0 现在在 System.Environment 中有一个 setEnv。因此,对于现在或不久的将来,它已经被整理出来了。

但是,如果您在 the commit that adds the feature 中提取了使该功能适用​​于较旧的基本版本所需的功能。

但是我对这个严重失去了耐心并且做得相当丑陋但它对我有用......

问题在于在 windows 环境中调用了 3 个函数:putenvSetEnvironmentVariableA (ASCII) 和 SetEnvironmentVariableW (widechar, utf16)。提交到 base 4.7 的补丁会自动执行此操作,但由于没有时间,我做了一些更丑陋的事情(我可能会清理它)。

这是我所拥有的:

setEnv_ :: String -> String -> IO () 
setEnv_ key value = withCString key $ \k -> withCString value $ \v -> do 
  success <- c_SetEnvironmentVariable k v 
  unless success (throwGetLastError "setEnv") 

putEnv :: String -> IO ()
putEnv v = void (withCString v $ \vv -> c_putenv vv)

foreign import stdcall unsafe "windows.h SetEnvironmentVariableA" 
  c_SetEnvironmentVariable :: CString -> CString -> IO Bool 

-- SetEnv_ :: String -> String -> IO () 
-- SetEnv_ key value = withCWString key $ \k -> withCWString value $ \v -> do 
--   success <- c_SetEnvironmentVariable k v 
--   unless success (throwGetLastError "setEnv") 
--  
-- Foreign import stdcall unsafe "windows.h SetEnvironmentVariableW" 
--   c_SetEnvironmentVariable :: LPTSTR -> LPTSTR -> IO Bool 

foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt 

显然使用CPP 将整个东西放在#ifdef 中,仅适用于Windows。如您所见,我有widechar 调用的代码,但我目前对其进行了评论。我认为对于我的用例来说,只需调用putenv 就足够了,但它可以正常工作。所以我是这样称呼它的:

setEnv_ "LANG" localeStr
putEnv $ "LANG=" ++ localeStr

我的问题是我在家里主要是一个 linux 用户,我不喜欢在家里做太多的 windows 工作,我花了 很多 精力来完成这个和其他在 Windows 上正常工作的东西,我不能让自己进一步清理它。但是有了这段代码和原始补丁,你应该可以在

【讨论】:

    【解决方案2】:

    在 POSIX 平台上,您可以使用 System.Posix.Env,它具有 putEnv 功能。这比运行 export 更便携,但不幸的是不是真正的跨平台。

    【讨论】:

    • 感谢您的回答。在发布问题后,我实际上看到了该模块,但我真的很想要可以在 Windows 上运行的东西。
    【解决方案3】:

    这不可能跨平台的一个提示是 Java API 没有putenv。 另见related post

    最常见用例的解决方案是在exec-ing 编程时传递适当构造的环境。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-28
      • 2020-12-04
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多