Idris标准库(或第三方库)中是否有一些模块可以允许用户使用Shell扩展到另一个程序?我在考虑像Pythonsubprocess
和Haskell这样的模块System.Process
。
理想情况下,我想以编程方式与该流程进行交互(写入其stdin,从其stdout读取等)。
有一个system : String -> IO Int
函数接受shell命令,然后运行它并返回其退出代码。您需要import System
使用它:
import System
main : IO ()
main = do
exitCode <- system "echo HelloWorld!"
putStrLn $ "Exit code: " ++ show exitCode
exitCode <- system "echo HelloWorld!; false"
putStrLn $ "Exit code: " ++ show exitCode
在我的系统上,以上代码导致以下输出:
HelloWorld!
Exit code: 0
HelloWorld!
Exit code: 256
我希望它返回,1
而不是256
第二种情况。至少它echo $?
显示了什么。
可以根据该Effects
库制作另一个版本,本教程对此进行了描述:
import Effects
import Effect.System
import Effect.StdIO
execAndPrint : (cmd : String) -> Eff () [STDIO, SYSTEM]
execAndPrint cmd = do
exitCode <- system cmd
putStrLn $ "Exit code: " ++ show exitCode
script : Eff () [STDIO, SYSTEM]
script = do
execAndPrint "echo HelloWorld!"
execAndPrint "sh -c \"echo HelloWorld!; exit 1\""
main : IO ()
main = run script
在这里,我们需要向Idris解释它需要该Effects
软件包:
idris -p effects <filename.idr>
我不知道有任何Idris库可让您轻松使用子进程的stdin / stdout。作为解决方法,我们可以使用C的管道功能,利用其popen
/pclose
函数,该区域在Idris标准库中具有绑定。让我展示一下如何例如从子流程的stdout中读取(请记住,这是一个带有基本错误处理的简单代码段):
import System
-- read the contents of a file
readFileH : (fileHandle : File) -> IO String
readFileH h = loop ""
where
loop acc = do
if !(fEOF h) then pure acc
else do
Right l <- fGetLine h | Left err => pure acc
loop (acc ++ l)
execAndReadOutput : (cmd : String) -> IO String
execAndReadOutput cmd = do
Right fh <- popen cmd Read | Left err => pure ""
contents <- readFileH fh
pclose fh
pure contents
main : IO ()
main = do
out <- (execAndReadOutput "echo \"Captured output\"")
putStrLn "Here is what we got:"
putStr out
运行程序时,您应该看到
Here is what we got:
Captured output
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句