Haskell 使用命令行中的文件参数与 “..” 一起。

huangapple go评论63阅读模式
英文:

haskell use file argument from command line with ".."

问题

使用 命令行解析器 提供一个包含文件名参数的字符串,而在这种情况下是 "../somedir"。如何将此字符串转换为类型安全的 相对路径目录,以便稍后与当前目录组合?

relDir1 <- parseRelDir fp

会引发错误(如描述中所指出的),因为它 "包含表示父目录的 .. 路径组件"。

尝试首先将当前目录与命令行中的字符串结合起来,如:

relDir2 <- parseRelDir (currDir </> fp)

返回相同的错误。

我找到了一个 "hack",使用来自 FileSystem.Pathcollapse,它需要一个 decodeString 和一个 encodeString,用于在字符串(又名 FilePath)和特殊使用的 FilePath 之间转换:

combPath = toFilePath currDir </> (locationDir $ flags) :: FilePath 
collPath = collapse . decodeString $ combPath   
absdir = makeAbsDir . encodeString $ collPath :: Path Abs Dir 

但是我想肯定有一个更好的方法来处理这个常见任务,假设在某处会有一个更好的方法。

英文:

Using a command line parser gives a string containing a filename argument, which in this case is "../somedir". How to convert this string into a typesafe Path Rel Dir from Path to combine later with the current directory?

relDir1 &lt;- parseRelDir fp

throws an error (as indicated in the description, because it "contains a .. path component representing the parent directory")

Trying to combine the currentDir with the String from the command line first, as in

relDir2 &lt;- parseRelDir (currDir &lt;/&gt; fp) 

returns the same error.

I found a "hack", using collapse from FileSystem.Path, which requires an decodeString and a encodeString to convert from String (aka FilePath) to the special FilePath used:

combPath = toFilePath currDir &lt;/&gt; (locationDir $ flags) :: FilePath 
collPath = collapse . decodeString $ combPath   
absdir = makeAbsDir . encodeString $ collPath :: Path Abs Dir 

but assume there is somewhere a better approach to this common task?

答案1

得分: 4

或许你正在寻找canonicalizePath。在 /home/<my-user> 中启动 ghci:

System.Directory> canonicalizePath ".."
"/home"
英文:

Perhaps you are looking for canonicalizePath. Starting ghci in /home/&lt;my-user&gt;:

System.Directory&gt; canonicalizePath &quot;..&quot;
&quot;/home&quot;

答案2

得分: 1

你链接到了 Path 包的文档。在该页面上搜索了一下,有 6 处提及了 ..,其中一处明确地回答了你的问题

> 有时候你会得到包含 ../ 的用户输入。我们采用的解决方案是使用类似于 resolveDir 函数(在 path-io 包中找到):

> resolveDir :: (MonadIO m, MonadThrow m)
> => Path Abs Dir -> FilePath -> m (Path Abs Dir)
>
> 它将调用 canonicalizePath 函数,该函数会折叠和规范化路径,然后我们使用常规的 parseAbsDir 进行解析,一切就都很顺利了。这个以及类似的函数可能会被添加到 path 包中。

英文:

You linked to the documentation of the Path package. There are 6 mentions of .. if you search that page, and one of them is clearly addressing your question:

> Sometimes you have user input that contains ../. The solution we went
> with is to have a function like resolveDir (found in path-io package):
>
> resolveDir :: (MonadIO m, MonadThrow m)
> => Path Abs Dir -> FilePath -> m (Path Abs Dir)
>
> Which will call canonicalizePath which collapses and normalizes a path and then
> we parse with regular old parseAbsDir and we’re cooking with gas. This
> and others like it might get added to the path package.

huangapple
  • 本文由 发表于 2023年3月31日 02:13:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75891639.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定