系统.进程如何保留shell会话而不是创建新进程


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" } 

但是,我必须解析前面的命令才能获得"一些目录">

有什么比解析命令更好的东西吗?

首先是一个工作代码示例:

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/test:的/tmp输出

"Sending pwd"
"reading response"
"/tmp"
"Sending cd test"
"reading response"
"Sending pwd"
"reading response"
"/tmp/test"
""
ExitSuccess

启动一个shell并将一个管道连接到其输入流,将一个管连接到其输出流。现在,您可以通过连接的管道向其输入流发送命令,并从其输出流读取响应。

但现在您需要一个协议,这样您就知道什么输出属于哪个命令。因此,您需要知道,例如,将为哪个输出生成多少输出行。例如,如果您试图读取cd test命令的响应,您的程序将挂起,因为没有任何输出。

还有其他方法可以解决这个问题,但它们都涉及某种启发式方法,并且超出了问题的范围。

您不能使用外部程序来更改当前的当前目录。那是行不通的。

正是由于这个原因,cd是一个shell内置运算符,而不是一个外部程序。(至少,Unix就是这么做的。我对Windows不是100%确定。(

请尝试使用setCurrentDirectory。这应该允许您更改Haskell程序的当前目录,然后该目录将在程序的剩余运行中保持永久性(或者直到您再次更改它(。

最新更新