3

Unicode ファイル パスを持つ Haskell から 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 が受け入れる形式の 1 つにエンコードするにはどうすればよいですか?

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.Char8ASCII 以外のテキストを処理する場合、これが正しい選択になることはほとんどありません。それはあなたのデータを破壊します。あなたの場合、おそらくData.ByteString.UTF8代わりに使用する必要があります(最新のデスクトップ Unix-y OS のほとんどに当てはまる UTF-8 ロケールを使用する場合)。

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"名前にいくつかのキリル文字を含むシェルスクリプトです) 内から私のために働きます。

もちろん、コマンド全体をエスケープすると、空白もエスケープされ、機能しません。コマンドの各単語を個別にエスケープします。

于 2013-07-05T14:37:04.040 に答える