Расширение пути в Хаскелле
Я хочу сделать функцию для расширения имен формы ~user
с домашним каталогом этого пользователя (обычно /home/user/
), в том числе ~root
, который обычно /root/
, Я знаю о getHomeDirectory
метод, чтобы получить дом текущего пользователя, но я не знаю ни одной функции, чтобы определить домашний каталог данного пользователя.
До сих пор
У меня есть следующая функция, которая заменяет ведущий ~
в любом пути к файлу с домашним каталогом пользователя
-- join path with '/', except at root
-- opposite of breakPath
rejoinPath :: [FilePath] -> FilePath
rejoinPath [] = ""
rejoinPath (p:ps)
| p == "/" = p ++ go ps
| otherwise = go (p:ps)
where
go :: [FilePath] -> FilePath
go [] = ""
go [p] = p
go (p:ps) = p ++ "/" ++ go ps
-- split path on '/', erasing separator except at root
-- opposite of rejoinPath
breakPath :: FilePath -> [FilePath]
breakPath [] = []
breakPath (c:cs)
| c == '/' = "/" : go "" cs
| otherwise = go [c] cs
where
go :: FilePath -> FilePath -> [FilePath]
go z [] = [z]
go z (c:cs)
| c == '/' = z : go "" cs
| otherwise = go (z ++ [c]) cs
expandHome :: FilePath -> IO FilePath
expandHome p = rejoinPath <$> (go $ breakPath p)
where
go [] = pure []
go (p:ps)
| p == "~" = do
home <- getHomeDirectory
pure $ home : ps
| otherwise = pure $ p : ps
Я понимаю, что getHomeDirectory
читает из HOME
переменная окружения, и что другие домашние каталоги будет значительно сложнее приобрести, но я надеюсь, что это не невозможно или слишком сложно.
Заметка
Сейчас меня интересуют только системы Linux; Я понимаю, что Windows и Mac имеют совершенно разные стили.
1 ответ
Похоже, что это доступно в пакете Unix с использованием getUserEntryForName, а затем homeDirectory
поле UserEntry
,
import System.Posix.User
main :: IO ()
main = do entry <- getUserEntryForName "djf"
putStrLn (homeDirectory entry)