2012-02-14 29 views
9

Tôi có thể dễ dàng đọc biến môi trường sử dụng System.Environment.getEnv. Tuy nhiên, System.Environment không có bất kỳ chức năng setEnv tương ứng nào (theo như tôi có thể biết).Làm cách nào để đặt biến môi trường theo cách đa nền tảng?

Làm cách nào để đặt biến môi trường từ chương trình Haskell? Tôi thích một giải pháp đa nền tảng hơn. (Vì vậy, chỉ cần thực hiện export VAR=val hoặc sử dụng System.Posix.Env không hoàn toàn là những gì tôi đang tìm kiếm.)

+1

Lưu ý rằng cơ sở 4.7.0 hiện có 'setEnv'. –

+0

@EmmanuelTouzery: Tuyệt vời. Bạn có thể đặt câu trả lời đó để làm tăng khả năng hiển thị không? Cảm ơn. –

Trả lời

3

Lưu ý rằng cơ sở 4.7.0 hiện có setEnv trong System.Environment. Vì vậy, cho hiện tại hoặc tương lai gần nó được sắp xếp.

Tuy nhiên nếu bạn cần tính năng này trong các phiên bản < 4.7.0 (trường hợp của tôi hiện tại), tôi cũng đã trích xuất từ ​​the commit that adds the feature các chức năng cần thiết để thực hiện công việc này với phiên bản cơ sở cũ hơn.

Tuy nhiên tôi nghiêm túc mất kiên nhẫn ngày này và đã làm nó khá xấu xí nhưng nó làm việc cho tôi ...

Các mớ hỗn độn là có 3 chức năng để gọi trong một môi trường cửa sổ: putenv, SetEnvironmentVariableA (ASCII) và SetEnvironmentVariableW (widechar, utf16). Các bản vá đã được cam kết cơ sở 4.7 thực hiện điều này tự động, nhưng tôi đã làm một cái gì đó xấu xí hơn bởi thiếu thời gian (tôi có thể nào nó sạch nó lên).

Dưới đây là những gì tôi có:

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 

Rõ ràng sử dụng CPP để đưa toàn bộ điều trong một #ifdef chỉ cửa sổ. Như bạn có thể thấy tôi có mã cho cuộc gọi widechar, nhưng tôi đã nhận xét nó hiện tại. Tôi nghĩ rằng cho trường hợp sử dụng của tôi nó có lẽ sẽ là đủ để chỉ cần gọi putenv nhưng cũng nó hoạt động như nó được. Vì vậy, đây là cách tôi gọi nó là sau đó:

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

Vấn đề của tôi là tôi là chủ yếu là sử dụng Linux ở nhà và tôi không thích làm quá nhiều công việc trên cửa sổ ở nhà, và tôi đặt rất nhiều của năng lượng để có được điều này và những thứ khác để làm việc đúng trên cửa sổ, và tôi không thể mang lại cho bản thân mình để làm sạch này lên hơn nữa. Nhưng với mã này và bản vá lỗi ban đầu bạn sẽ nhận được điều này để làm việc trên cơ sở < 4.7 mà không có nhiều vấn đề.

3

Trên nền tảng POSIX bạn có thể sử dụng System.Posix.Env, có chức năng putEnv. Đó là di động hơn chạy export, mặc dù tiếc là không thực sự đa nền tảng.

+1

Cảm ơn câu trả lời. Tôi thực sự thấy rằng mô-đun sau khi đăng câu hỏi, nhưng tôi thực sự muốn một cái gì đó mà sẽ làm việc trên Windows. –

3

Một gợi ý rằng đây không phải là nền tảng chéo có thể là Java API không có putenv. Xem thêm điều này related post.

Giải pháp cho trường hợp sử dụng thường xuyên nhất là chuyển một môi trường được xây dựng thích hợp khi exec -ing chương trình.

Các vấn đề liên quan