Me encuentro haciendo más y más scripts en haskell. Pero hay algunos casos en los que realmente no estoy seguro de cómo hacerlo "bien".
p. copiar un directorio recursivamente (a la unix cp -r
).¿Cuál es la forma de haskell para copiar un directorio?
Desde que todo utilizar Linux y Mac OS por lo general trampa:
import System.Cmd
import System.Exit
copyDir :: FilePath -> FilePath -> IO ExitCode
copyDir src dest = system $ "cp -r " ++ srC++ " " ++ dest
pero lo que es la forma recomendada para copiar un directorio de una manera independiente de la plataforma?
No encontré nada adecuado en hackage.
Esta es mi aplicación en lugar naiv utilizo hasta el momento:
import System.Directory
import System.FilePath((</>))
import Control.Applicative((<$>))
import Control.Exception(throw)
import Control.Monad(when,forM_)
copyDir :: FilePath -> FilePath -> IO()
copyDir src dst = do
whenM (not <$> doesDirectoryExist src) $
throw (userError "source does not exist")
whenM (doesFileOrDirectoryExist dst) $
throw (userError "destination already exists")
createDirectory dst
content <- getDirectoryContents src
let xs = filter (`notElem` [".", ".."]) content
forM_ xs $ \name -> do
let srcPath = src </> name
let dstPath = dst </> name
isDirectory <- doesDirectoryExist srcPath
if isDirectory
then copyDir srcPath dstPath
else copyFile srcPath dstPath
where
doesFileOrDirectoryExist x = orM [doesDirectoryExist x, doesFileExist x]
orM xs = or <$> sequence xs
whenM s r = s >>= flip when r
Cualquier sugerencia de lo que realmente es la manera de hacerlo?
He actualizado esto con las sugerencias de hammar y FUZxxl.
... pero aún así me parece algo torpe para una tarea tan común.
Si no existe dicha biblioteca estándar, ¿por qué no hacer uno? ;) –
Creo que esto no maneja los enlaces simbólicos correctamente. Debería recrearlos. Ver System.Posix.Files. – hasufell
El código no funciona si src y dst no son disjuntos. 'copyDir" A "" A/B "' se repetirá infinitamente. Consulte también https://github.com/yesodweb/Shelly.hs/issues/154 –