Haskell的shake/command库执行cd命令提示目录不存在问题求助
问题根因
你遇到的报错和目录是否存在没有任何关系,核心是两个错误用法:
cd是shell内置命令,不是系统中独立存在的可执行二进制文件。Shake的cmd/command默认会直接查找系统可执行文件启动进程,不会默认加载shell环境,自然找不到cd这个可执行程序,就会抛出exec: does not exist的错误。- 即便你通过配置让cmd启动shell执行
cd命令也没有意义:每一次cmd调用都会启动独立的子进程,cd只会修改当前子进程的工作目录,后续其他cmd调用的子进程、主进程的工作目录都不会发生变化,完全达不到切换目录执行后续git命令的效果。
正确实现方式
Shake的cmd本身就支持通过Cwd参数指定命令运行的工作目录,根本不需要主动调用cd命令。
另外你的代码还有逻辑错误:你当前定义的gitPath指向的是.git目录本身,直接mkdir -p创建.git目录后再执行git init会出现冲突,git init会自动在目标目录下创建.git文件夹,不需要提前创建。
修正后的代码示例:
dataDir = "data" data Settings = Settings { url :: String } deriving (Eq, Show, Generic, JSON.ToJSON, JSON.FromJSON) settings :: String -> Handler Settings settings subfolder = let -- 这里改为指向git工作目录,而非内部的.git目录 gitWorkDir = dataDir ++ "/" ++ subfolder ++ "/git" gitDotGitPath = gitWorkDir ++ "/.git" in do pathExists <- liftIO $ doesPathExist gitDotGitPath if not pathExists then do -- 只需要创建到git工作目录层级即可 liftIO $ cmd_ ("mkdir -p" :: String) [gitWorkDir] :: IO () -- 直接通过Cwd参数指定git init的运行目录 liftIO $ cmd_ (Cwd gitWorkDir) ("git init" :: String) :: IO () return $ Settings { url = ""} else do -- 执行git命令时直接指定工作目录 Stdout out <- liftIO $ cmd (Cwd gitWorkDir) ("git config --get remote.origin.url" :: String) return $ Settings {url = out}
内容的提问来源于stack exchange,提问作者altern
相关产品推荐
相关产品推荐

