3

我想从 Haskell 运行一个具有 unicode 文件路径的 bash 命令。

Haskell 中的字符串使用 \escapes 例如

"beißen" -> "bei\223en"

Bash 似乎接受以下格式:

$'bei\xC3\x9Fen.avi''beißen.avi'

因为runCommandfromSystem.Process有类型

runCommand :: String -> IO System.Process.Internals.ProcessHandle

如何将 Haskell 字符串编码为 Bash 接受的格式之一?

使用具有 bash 3.2 的 Mac OSX 10.8.4 。

编辑

我的问题似乎与 bash 转义有关

我正在使用Text.ShellEscapehttp://hackage.haskell.org/packages/archive/shell-escape/0.1.2/doc/html/Text-ShellEscape.html)来转义需要为 bash 转义的字符

例如

import qualified Data.ByteString.Char8 as B
import qualified Text.ShellEscape as Esc
let cmd = B.unpack $  Esc.bytes    $  Esc.bash . B.pack $ "beißen.txt"

这给了我"$'bei\\xDFen.txt'"

跑步时runCommand $ "ls " ++ cmd

它给了我 ls: bei�en.txt: No such file or directory

是否有更好的方法来为 bash 转义字符串?

4

1 回答 1

4

Data.ByteString.Char8如果要处理非 ASCII 文本,这几乎不是正确的选择。它会破坏你的数据。在您的情况下,您可能应该Data.ByteString.UTF8改用(前提是您使用 UTF-8 语言环境,这是大多数现代桌面 Unix-y 操作系统的情况)。

修改数据示例Data.ByteString.Char8

Prelude Data.ByteString.Char8> "été"
"e\769te\769"
Prelude Data.ByteString.Char8> unpack $ pack "été"
"e\SOHte\SOH"
Prelude Data.ByteString.Char8> Prelude.putStrLn "été"
été
Prelude Data.ByteString.Char8> Prelude.putStrLn $ unpack $ pack "été"
ete

Data.ByteString.UTF8.toString而不用Data.ByteString.Char8.unpack

这些调用

let s = toString $ bytes $ bash $ fromString "мама.sh"
runCommand s
runCommand $ "ls -l " ++ s

在 ghci 中为我工作("мама.sh"是一个名称中带有一些西里尔字符的 shell 脚本)。

当然,如果您转义整个命令,它也会转义空白,并且将无法正常工作。单独转义命令的每个单词。

于 2013-07-05T14:37:04.040 回答