• # Montre-moi ton Shell typé !

    Posté par . En réponse au journal Gufo: un langage de shell moderne!. Évalué à 4.

    Votre avis me sera utile pour savoir si le projet semble avoir du sens.

    "From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds)
    Date: 25 Aug 91 20:57:08 GMT
    [...] just a hobby, won’t be big and professional [...]"

    Pour le reste, dans l'esprit du commentaire de Michaël, je dirais que l'approche la moins bidouilleuse serait de partir sur un langage de haut niveau, statiquement typé et de le doter d'une interface adéquate par rapport à tes besoins. Ici, le domaine interface est bien défini, c'est le Shell. Je propose alors Haskell comme langage et turtle comme bibliothèque procurant une interface mimant le Shell. Gabriel Gonzalez a écrit un excellent tutoriel sur cette bibliothèque auquel je renvoie au lieu de tenter de présenter la chose ici ; voici plutôt un exemple adapté des cas d'utilisations présentés dans le journal.

    #!/home/foo/.local/bin/stack
    -- stack runghc --package turtle
    {-# LANGUAGE OverloadedStrings #-}
    import Turtle (
     ( <$> )
     , Alternative ( empty )
     , Applicative ( pure )
     , FilePath
     , MonadIO
     , Text
     , fold
     , input
     , inshell
     , lineToText
     , ls
     , output
     , unsafeTextToLine
     , view
     )
    import Control.Foldl ( head, length )
    import Data.Text ( concat, pack )
    import Prelude ( ( . ), ( >> ), Maybe ( Just, Nothing ), Show ( show ) )
    main = eg1
     >> eg2 "nb_files.txt"
     >> eg3 "ls" "ls_opts" "log_ls"
    -- ls
    eg1 = ( view . ls ) "."
    -- ls -l | wc -l > nb_files.txt
    eg2 outFile = do
     fileCount <- fold ( ls "." ) length
     outFile `output` ( pure . unsafeTextToLine . pack . show ) fileCount
    -- Variation sur le thème « exécuter [un] programme externe [...] prenant en paramètre une chaine de caractères [contenue dans un fichier ...] »
    eg3 :: MonadIO io => Text -> FilePath -> FilePath -> io ()
    eg3 prog optFile logFile = do
     mayOpts <- fold ( lineToText <$> input optFile ) head
     case mayOpts of
     Nothing -> output logFile ( inshell "Bad options" empty )
     Just opts -> output logFile ( concat [ prog, " ", opts ] `inshell` empty )

    En rendant hommage au problème de l’œuf et de la poule, testons ce script (nommé code.hs) sous Bash.

    mkdir woe
    pushd woe
    touch ceci cela ça
    printf '%s\n' '-l --human-readable --context' > ls_opts
    chmod u+x code.hs
    ./code.hs
    cat log_ls

    Les sorties :

    FilePath "./code.hs"
    FilePath "./ls_opts"
    FilePath "./231円a"
    FilePath "./cel224円"
    FilePath "./ceci"
    -rw-r-----. 1 foo foo unconfined_u:object_r:user_home_t:s0...

    Bref, cette bibliothèque et le Shell, c'est comme les chéloniens et les carapaces. Cependant, comme sous-entendu au début de ce commentaire, que rien ne t'arrête dans tes expérimentations car, après tout, un OS entier est né par bidouillage.