Klaus Alexander Seistrup
2009-01-10 01:23:36 UTC
Hej gruppe
Jeg har et binært program der forventer input i ISO-8859-1, og som
osse leverer uddata i ISO-8859-1. Jeg skal nu bruge programmet på
en linuxbaseret pc der kører UTF-8 som tegnsæt, og jeg tænkte at
det vil være enklere at skrive et wrapper-script til programmet end
at skulle skrive hele programmet om (det behandler osse data internt
i ISO-8859-1, så det er ikke helt enkelt at skulle skrive rutinerne
om, selv om programmet ikke er så stort).
Nuvel, taktikken er at konvertere kommandolinjeargumenterne manuelt,
og så bruge codecs.EncodedFile() til at sørge for at stdio er ind-
kodet med det korrekte tegnsæt på det rigtige sted. Det virker
næsten.
Programmet ser således ud i barberet udgave:
#v+
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import os
import locale
import codecs
import subprocess
DEBUG = os.environ.get('DEBUG', False)
locale.setlocale(locale.LC_ALL, '')
encoding = locale.getlocale()[1] or 'utf-8'
if DEBUG:
print encoding, locale.getpreferredencoding()
args = map(lambda s: unicode(s, encoding).encode('iso-8859-1'), sys.argv)
# Her er det program som skal wrappes:
args[0] = '/usr/bin/programnavn'
fi = codecs.EncodedFile(sys.stdin, encoding, 'iso-8859-1', errors='replace')
fo = codecs.EncodedFile(sys.stdout, 'iso-8859-1', encoding, errors='replace')
fe = codecs.EncodedFile(sys.stderr, 'iso-8859-1', encoding, errors='replace')
if DEBUG:
for arg in args:
fo.write(arg + '\n')
sys.exit(subprocess.call(args, stdin=fi, stdout=fo, stderr=fe))
# eof
#v-
Det er ganske let at forvisse sig om at de tre streams (fi, fo & fe)
fungerer efter hensigten. Problemet synes at være at call() helt
ignorerer de filepointere jeg giver den.
Er der nogen der kan greje hvorfor det går galt, eller som har et
forslag til en løsning der virker?
På forhånd tak for hjælpen.
PS: Som kuriositet er her en wrapper skrevet i bash som virker:
#v+
#!/bin/bash
declare -a args
declare -i i=0
for arg in "${@}"
do
args[${i}]="$(iconv -f utf-8 -t iso-8859-1 <<< ${arg})"
i=$((i+1))
done
/usr/bin/programnavn "${args[@]}" | iconv -f iso-8859-1 -t utf-8
:
# eof
#v-
Mvh,
Jeg har et binært program der forventer input i ISO-8859-1, og som
osse leverer uddata i ISO-8859-1. Jeg skal nu bruge programmet på
en linuxbaseret pc der kører UTF-8 som tegnsæt, og jeg tænkte at
det vil være enklere at skrive et wrapper-script til programmet end
at skulle skrive hele programmet om (det behandler osse data internt
i ISO-8859-1, så det er ikke helt enkelt at skulle skrive rutinerne
om, selv om programmet ikke er så stort).
Nuvel, taktikken er at konvertere kommandolinjeargumenterne manuelt,
og så bruge codecs.EncodedFile() til at sørge for at stdio er ind-
kodet med det korrekte tegnsæt på det rigtige sted. Det virker
næsten.
Programmet ser således ud i barberet udgave:
#v+
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import os
import locale
import codecs
import subprocess
DEBUG = os.environ.get('DEBUG', False)
locale.setlocale(locale.LC_ALL, '')
encoding = locale.getlocale()[1] or 'utf-8'
if DEBUG:
print encoding, locale.getpreferredencoding()
args = map(lambda s: unicode(s, encoding).encode('iso-8859-1'), sys.argv)
# Her er det program som skal wrappes:
args[0] = '/usr/bin/programnavn'
fi = codecs.EncodedFile(sys.stdin, encoding, 'iso-8859-1', errors='replace')
fo = codecs.EncodedFile(sys.stdout, 'iso-8859-1', encoding, errors='replace')
fe = codecs.EncodedFile(sys.stderr, 'iso-8859-1', encoding, errors='replace')
if DEBUG:
for arg in args:
fo.write(arg + '\n')
sys.exit(subprocess.call(args, stdin=fi, stdout=fo, stderr=fe))
# eof
#v-
Det er ganske let at forvisse sig om at de tre streams (fi, fo & fe)
fungerer efter hensigten. Problemet synes at være at call() helt
ignorerer de filepointere jeg giver den.
Er der nogen der kan greje hvorfor det går galt, eller som har et
forslag til en løsning der virker?
På forhånd tak for hjælpen.
PS: Som kuriositet er her en wrapper skrevet i bash som virker:
#v+
#!/bin/bash
declare -a args
declare -i i=0
for arg in "${@}"
do
args[${i}]="$(iconv -f utf-8 -t iso-8859-1 <<< ${arg})"
i=$((i+1))
done
/usr/bin/programnavn "${args[@]}" | iconv -f iso-8859-1 -t utf-8
:
# eof
#v-
Mvh,
--
Klaus Alexander Seistrup
http://klaus.seistrup.dk/
Klaus Alexander Seistrup
http://klaus.seistrup.dk/