Jonathan
Jonathan

Reputation: 11321

In Turtle (Haskell), how can I get the output of a command, and do something with it?

I'm a Haskell beginner, trying to translate a shell script into a Turtle script, just as an exercise. In BASH, I'd get the output of some command like so: cmdoutput=$(my-command -option 1 -option 2 and then I could do a case switch in BASH to echo out different messages or run different actions, depending on the value of cmdoutput. How can I achieve that in Haskell Turtle?

Edit: here's the shell script I'm trying to translate:

#!/usr/bin/bash

export CLOCKSTRING=$(emacsclient --eval '(if (org-clocking-p)(org-clock-get-clock-string) -1)' 2>&1 )

case "$CLOCKSTRING" in
    "-1")
        echo "Off!" ;;
    *"server-start"*)
        echo "Off!" ;;
    *"ERROR"*)
        echo "No clock!" ;;
    *)
        echo ${CLOCKSTRING:3:30} ;
esac

And here's what I have so far with Turtle:

{-# LANGUAGE OverloadedStrings #-}

import Turtle
import qualified Control.Foldl as Fold

translate :: Text -> Text
translate response = case response of
 "-1" -> "Got nothin"
 otherwise -> response

main = do
  let cmd2 = "emacsclient --eval '(if (org-clocking-p)(org-clock-get-clock-string) -1)'"

  emacsOut <- fold (inshell cmd2 empty) Fold.head
  print $ translate $ emacsOut

Upvotes: 2

Views: 280

Answers (2)

luochen1990
luochen1990

Reputation: 3847

You can use shellStrict, and following is my abstracted tool shEval which is implemented via shellStrict:

shEval :: Partial => Text -> IO Text
shEval cmd = do
    (rst, out) <- Turtle.shellStrict cmd empty
    case rst of
        Turtle.ExitSuccess -> pure out
        Turtle.ExitFailure code -> terror ("shell process exit with non-zero code (" ++ tshow code ++ ")")

Upvotes: 0

You can use inshell to run a command and capture its output.

inshell "my-command -option 1 -option 2" empty

Note that that assumes you're in the Shell monad, not the IO monad. If you're in the latter, you'd need to consume it somehow, such as by folding:

import qualified Control.Foldl as Fold
fold (inshell "echo abc\necho def" empty) Fold.list

Edit: Your attempt with translate was close. Try like this:

translate :: Maybe Line -> String
translate response = case lineToText <$> response of
 Just "-1" -> "Got nothin"
 otherwise -> show response

Upvotes: 1

Related Questions