You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:09:02