import System.Process
createProcess (shell "pwd") -- /Users/username/current-directory
createProcess (shell "cd app") -- LOST
createProcess (shell "pwd") -- /Users/username/current-directory
很显然,createProcess (shell "cd app")
在下一个过程中不是持久的。
但是,如何保持会话的持久性?
我知道我可以通过cwd
,但是
createProcess (shell "mkdir some-dir && cd some-dir")
createProcess (shell "pwd") { cwd = Just "some-dir" }
但是,我必须解析前面的命令以获取“ some-dir”。
有比解析命令更好的东西吗?
答案 0 :(得分:2)
首先是一个工作代码示例:
module Main where
import System.Process
import System.IO
ourShell :: CreateProcess
ourShell = (proc "/bin/bash" []) { std_in = CreatePipe, std_out = CreatePipe }
main = do
(Just bashIn, Just bashOut, Nothing, bashHandle) <- createProcess ourShell
hSetBuffering bashIn NoBuffering
hSetBuffering bashOut NoBuffering
print "Sending pwd"
hPutStrLn bashIn "pwd"
print "reading response"
hGetLine bashOut >>= print
print "Sending cd test"
hPutStrLn bashIn "cd test"
print "reading response"
-- hGetLine bashOut >>= print you need to know there is no answer ....
print "Sending pwd"
hPutStrLn bashIn "pwd"
print "reading response"
hGetLine bashOut >>= print
hPutStrLn bashIn "exit"
hGetContents bashOut >>= print
ec <- waitForProcess bashHandle
print ec
这会在我的计算机上以/tmp
的现有/tmp/test
输出:
"Sending pwd"
"reading response"
"/tmp"
"Sending cd test"
"reading response"
"Sending pwd"
"reading response"
"/tmp/test"
""
ExitSuccess
启动外壳程序,然后将管道连接到其输入流,并将管道连接到其输出流。现在,您可以将命令发送到其输入流,并通过连接的管道读取其输出流的响应。
但是现在您需要一个协议,因此您知道哪个输出属于哪个命令。因此,您需要知道例如将为哪个输出生成多少条输出线。例如,如果您尝试读取cd test
命令的响应,则程序将挂起,因为没有任何输出。
还有其他方法可以解决此问题,但是它们都涉及某种启发式方法,超出了问题的范围。
答案 1 :(得分:1)
您不能使用外部程序来更改 current 程序的当前目录。那只是行不通的。
因此,cd
是Shell内置的运算符,而不是外部程序。 (至少,这就是Unix的工作方式。我对Windows并非100%肯定。)
尝试改用setCurrentDirectory。那应该允许您更改Haskell程序的当前目录,该目录将在程序的其余运行期间保持永久(或直到您再次更改它)。