我想从Haskell运行一个带有unicode文件路径的bash命令。
Haskell中的字符串使用\ escapes,例如
"beißen" -> "bei\223en"
Bash似乎接受以下格式:
$'bei\xC3\x9Fen.avi'
和'beißen.avi'
因为runCommand
中的System.Process
具有类型
runCommand :: String -> IO System.Process.Internals.ProcessHandle
如何将Haskell字符串编码为Bash接受的格式之一?
使用具有bash 3.2的Mac OSX 10.8.4。
修改
我的问题似乎与bash转义有关
我使用Text.ShellEscape
(http://hackage.haskell.org/packages/archive/shell-escape/0.1.2/doc/html/Text-ShellEscape.html)来逃避需要为bash转义的字符
e.g
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转义字符串吗?
答案 0 :(得分:4)
Data.ByteString.Char8
几乎永远不是正确的选择。它会破坏你的数据。在您的情况下,您可能应该使用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脚本,名称中包含一些西里尔字符)。
当然,如果你逃避整个命令,它也会逃离空白区域,它将无法正常工作。单独逃避命令的每个单词。