能否通过Here文档向runhaskell传递指定输入内容?
问题
我希望将字符串"Hello World"传递给以下位于Here文档中的Haskell脚本:
main :: IO () main = interact id
请问是否可以实现这一需求?我已编写了一个最小可复现示例,但目前无法正常运行:
#!/bin/bash echo "Hello World" | runhaskell <<HASKELL_END 2>/dev/null main :: IO () main = interact id
原因分析
你的脚本无法运行的核心问题是:runhaskell默认会从标准输入读取脚本内容,而你同时用管道把"Hello World"传给它的标准输入,这就导致标准输入被Here文档的脚本内容占用,管道的字符串根本无法传递给Haskell程序的输入。
解决方案
你可以通过以下几种方法实现需求:
方法一:使用进程替换分离脚本和输入来源
用进程替换<()将Here文档的脚本内容转为临时文件路径,让runhaskell读取这个文件作为脚本,管道的内容则作为Haskell程序的标准输入:
#!/bin/bash echo "Hello World" | runhaskell <(cat <<HASKELL_END main :: IO () main = interact id HASKELL_END )
方法二:先将脚本写入临时文件再执行
把Here文档的脚本保存到临时文件,再让runhaskell加载该文件,同时通过管道传递输入:
#!/bin/bash # 写入临时脚本文件 cat > temp_script.hs <<HASKELL_END main :: IO () main = interact id HASKELL_END # 传递输入并执行脚本 echo "Hello World" | runhaskell temp_script.hs # 清理临时文件 rm temp_script.hs
方法三:通过文件描述符传递输入
将管道输入重定向到其他文件描述符,让runhaskell从标准输入读脚本,Haskell程序从指定描述符读输入:
#!/bin/bash echo "Hello World" | runhaskell <<HASKELL_END 3<&0 import System.IO main :: IO () main = do input <- hGetContents (fdToHandle 3) putStr input HASKELL_END
这种方法需要修改Haskell代码,显式从文件描述符3读取输入,避免和runhaskell读取脚本的标准输入冲突。
内容的提问来源于stack exchange,提问作者F. Zer
相关产品推荐
相关产品推荐

