I'm using scotty and I'm getting the same type error any way I try to execute a shell script from a POST request.
main = scotty 3000 $ do
post "MyPage/ScriptTime/run" $ do
aparameter <- param "aparameter"
bparameter <- param "bparameter"
cparameter <- param "cparameter"
dparameter <- param "dparameter"
eparameter <- param "eparameter"
rawSystem "./shellscript.sh" [ "-a"
, aparameter
, "-b"
, bparameter
, "-c"
, cparameter
, dparameter
, eparameter
]
Using the answers on Is it possible to invoke bash or shell scripts from a haskell program? and Executing a system command in Haskell have not helped me change the error message.
The error reads:
Main.hs:68:5: error:
• Couldn't match type ‘IO’
with ‘Web.Scotty.Internal.Types.ActionT
Data.Text.Internal.Lazy.Text IO’
Expected type: Web.Scotty.Internal.Types.ActionT
Data.Text.Internal.Lazy.Text IO ()
Actual type: IO GHC.IO.Exception.ExitCode
• In a stmt of a 'do' block:
rawSystem "./shellscript.sh" ["-a", aparameter, "-b", bparameter, ....]
In the second argument of ‘($)’, namely
‘do aparameter <- param "aparameter"
bparameter <- param "bparameter"
cparameter <- param "cparameter"
dparameter <- param "dparameter"
....’
I've changed the function and library used for invoking the shell script several ways, including:
() <- createProcess (proc "./shellscript.sh" ["-a", aparameter, "-b", bparameter, ...])
runProcess (shell "./shellscript.sh -a aparameter -b bparameter ...") >>= print
I have tried using System.Process, System.Process.Typed, and System.Cmd libraries.
Can someone help me understand my type mismatch.
The mismatch is in the monad in which the functions run. rawSystem
runs in the IO
monad, as indicated by its type, as well as in the error message. But scotty
's run
function expects a thing that runs in the ActionT e m
monad.
The error message tells you as much: cannot match type IO _
with ActionT Text IO _
.
Since ActionT
has an instance of MonadTrans
, you can just lift
an IO
function into ActionT _ IO
:
lift $ rawSystem "./shellscript.sh" [...]
After you have done that, your next problem will be the return type: rawSystem
returns an ExitCode
, while scotty
's run
function expects unit. If you're ok just throwing away the exit code (though I don't recomment it), you can either bind it to an unnamed variable:
_ <- lift $ rawSystem ...
pure ()
Or, better yet, you can use void
to discard the value:
void . lift $ rawSystem ...