如何以跨平台的方式设置环境变量?

10

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

如何从Haskell程序中设置环境变量?我希望能得到跨平台的解决方案。(因此仅执行export VAR=val或使用System.Posix.Env并不完全符合我的要求。)


1
请注意,基础版本4.7.0现在具有setEnv - Emmanuel Touzery
@EmmanuelTouzery:太棒了。你能把它作为答案放上去以增加可见性吗?谢谢。 - Tikhon Jelvis
3个回答

4
请注意,基础版本4.7.0现在在System.Environment中具有setEnv。因此,就目前或不久的将来而言,已经解决了这个问题。
然而,如果您需要在版本小于4.7.0(这是我目前的情况)中使用此功能,则我还从添加该功能的提交中提取了所需的函数,以使其与旧版基础版本兼容。
但是,我对此非常失去耐心,做得相当丑陋,但对我来说有效...
混乱之处在于在Windows环境中有3个要调用的函数:putenv、SetEnvironmentVariableA(ASCII)和SetEnvironmentVariableW(widechar,utf16)。提交到基础版本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。正如您所看到的,我已经有了宽字符调用的代码,但目前我已经注释掉了它。我认为对于我的用例,只调用putenv可能就足够了,但是现在这样也可以工作。那么下面是我如何调用它:

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

我的问题是,我主要在家使用 Linux,不太喜欢在 Windows 上工作,而且我花了很多精力让这个和其他东西在 Windows 上正常工作,我无法再进一步清理它。但是通过这段代码和原始补丁,你应该可以在基础版本小于4.7的情况下轻松解决这个问题。

3
在POSIX平台上,您可以使用System.Posix.Env,该库有一个putEnv函数。与运行export相比,这更具可移植性,尽管不是真正的跨平台。

1
谢谢你的回答。实际上,在发布问题后我看到了那个模块,但我真的想要在Windows上运行的东西。 - Tikhon Jelvis

2

提示跨平台不可能的一点是Java API没有putenv函数。参见这个相关帖子

最常见的解决方案是在exec程序时传递一个适当构造的环境变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接