使用 scotty 从 POST 请求执行 shell 脚本

Execute shell script from a POST request with scotty

我正在使用 scotty,但我在尝试从 POST 请求执行 shell 脚本时遇到相同类型的错误。

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
                                   ]

使用 Is it possible to invoke bash or shell scripts from a haskell program? and Executing a system command in Haskell 上的答案并没有帮助我更改错误消息。

错误为:

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"
        ....’

我已经通过多种方式更改了用于调用 shell 脚本的函数和库,包括:

() <- createProcess (proc "./shellscript.sh" ["-a", aparameter, "-b", bparameter, ...])

runProcess (shell "./shellscript.sh -a aparameter -b bparameter ...") >>= print

我尝试过使用 System.Process、System.Process.Typed 和 System.Cmd 库。

谁能帮我理解我的类型不匹配。

不匹配出现在函数 运行 所在的 monad 中。 rawSystem 运行s 在 IO monad 中,如 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 所示。

错误消息告诉您:cannot match type IO _ with ActionT Text IO _.

因为 ActionT 有一个 MonadTrans 的实例,你可以 lift 一个 IO 函数到 ActionT _ IO:

lift $ rawSystem "./shellscript.sh" [...]

完成后,您的下一个问题将是 return 类型:rawSystem returns 和 ExitCode,而 scotty's run 函数需要单位。如果你可以直接扔掉退出代码(虽然我不推荐它),你可以将它绑定到一个未命名的变量:

_ <- lift $ rawSystem ...
pure ()

或者,更好的是,您可以使用 void 丢弃值:

void . lift $ rawSystem ...