-- hsh is a basic haskell shell, a tool written in haskell to mimic shell commands -- in a basic form module Main where import System.Environment import System.Directory import System.Exit import System.Info import System.Posix.Unistd import Data.Version import Data.List import Data.Maybe import Text.Printf import Text.Regex -- main functions main = getArgs >>= parse >> succeed hshversion = printf "haskell hsh v0.4, compiled with %s-%s, running on %s-%s\n" compilerName (showVersion compilerVersion) os arch >> succeed usage = printf "usage: hsh [COMMANDS...] [OPTIONS]\n" succeed = exitWith ExitSuccess failure = exitWith (ExitFailure 1) -- parse functions -- command options parse ("cat":xs) = cat xs >> succeed parse ("tac":xs) = tac xs >> succeed parse ("ls":xs) = ls xs >> succeed parse ("wc":xs) = wc xs >> succeed parse ("rm":xs) = rm xs >> succeed parse ("rmdir":"-r":xs) = recurmdir xs >> succeed parse ("rmdir":xs) = rmdir xs >> succeed parse ("whereis":xs) = whereis xs >> succeed parse ("mv":xs) = mv xs >> succeed parse ("mvdir":xs) = mvdir xs >> succeed parse ("cp":xs) = cp xs >> succeed parse ("uname":xs) = uname xs >> succeed parse ("grep":x:_) = grep x >> succeed --help options and default cases parse ["-h"] = usage >> succeed parse ["-v"] = hshversion >> succeed parse (_:xs) = usage >> failure parse [] = usage >> failure -- here are the shell command 'miniatures' cat xs = interact id tac xs = interact (unlines . reverse . lines) ls [] = ls ["."] ls (x:xs) = do b <- doesDirectoryExist x if b == True then do c <- getDirectoryContents x ls2 c else do printf "ls err: directory '%s' does not exist\n" x failure ls2 [] = succeed ls2 (x:xs) = putStrLn (x) >> ls2 xs count s = show (length s) ++ "\n" wc xs = interact (count . lines) whereis (x:_) = do f <- findExecutable x putStrLn (x ++ ": " ++ fromMaybe "could not find executable" f) rm [] = succeed rm (x:xs) = removeFile x >> rm xs rmdir [] = succeed rmdir (x:xs) = removeDirectory x >> rmdir xs recurmdir [] = succeed recurmdir (x:xs) = removeDirectoryRecursive x >> recurmdir xs mv [] = succeed mv [_] = putStrLn "unmatched amount of options" >> failure mv (o:n:xs) = renameFile o n >> mv xs mvdir [] = succeed mvdir [_] = putStrLn "unmatched amount of options" >> failure mvdir (o:n:xs) = renameDirectory o n >> mvdir xs cp [] = succeed cp [_] = putStrLn "unmatched amount of options" >> failure cp (o:n:xs) = copyFile o n >> cp xs uname _ = do s <- getSystemID putStrLn (concat (intersperse " " [systemName s,nodeName s,release s,version s,machine s])) succeed checkword x s = case z of Nothing -> False Just _ -> True where z = matchRegex (mkRegex x) s grep x = interact (unlines . filter (checkword x) . lines)