LINUX.ORG.RU

[tcl] string to... и UTF-8

 


0

1

string tolower поганит кодировку в скрипте. Вот во что превращается Барабан: р‘р°сЂр°р±р°рЅ

Ну и с totitle такая же картина - Р±р°сЂр°р±р°рЅ

toupper не оказывает никакого влияния - регистр не меняется.

В консоле все нормально.

Строка выглядит так: set teg [string tolower [string trim $teg]]. Если убрать tolower (set teg [string trim $teg]) все работает отлично.

Из этого скрипта пишутся разные строки в разные файлы - проблема только здесь. Где изменения регистра нет - нет и проблемы.

Интерпретаторы 8.5 и 8.6.

★★★★★

Последнее исправление: Suntechnic (всего исправлений: 1)

Вобщем трабла конечно же оказалась в том, что скрипт работает от другого юзера - www-data, а кодировка у него POSIX.

Плохо то, что хотя

set env(LANG) ru_RU.UTF-8
set env(LOCALE) ru_RU.UTF-8
меняют кодировку на нужную, эффекта это не оказывает. Не помогает даже добавление encoding system utf-8...

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

ага. Натыкался на похожее при попытке послать письмо через smtp и mime с кодировкой win. Решилось костылем в виде шеллового скрипта, в котором сначала выставлялись и экспортировались нужные переменные окружения LC_ALL, LANG и может еще какие-то и затем только запускался тиклевый скрипт.

anonymous
()
Ответ на: комментарий от geekless

Ежели бы так... Пробовал сделать так:

#!/bin/sh
# \
env LANG=ru_RU.utf8 tclsh "$0" ${1+"$@"};
Вообще интересно получается - на выводится на stdout (то есть апачу отдаваться) начинает нормально, а в файл все равно пишется белеберда.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

Странно. УМВР.

vadim@host3:~/tmp$ pacman -Qi tcl
Название              : tcl
Версия                : 8.5.10-1
URL                   : http://tcl.sourceforge.net/
Лицензии              : custom
Группы                : Нет
Предоставляет         : Нет
Зависит от            : glibc
Дополнительно         : Нет
Требуется пакетами    : bwidget  expect  tcllib  tk  tkabber  tls
Конфликтует с         : Нет
Заменяет              : Нет
Размер установленного : 5912,00 K
Сборщик               : Allan McRae <allan@archlinux.org>
Архитектура           : i686
Дата сборки           : Сб. 25 июня 2011 22:00:44
Дата установки        : Сб. 09 июля 2011 16:09:44
Причина установки : Установлен как зависимость другого пакета
Установочный скрипт   : No
Описание              : The Tcl scripting language

vadim@host3:~/tmp$ set | egrep '^LANG|^LC_'
LANG=ru_RU.UTF-8
LANGUAGE=ru_RU.utf8
LC_MESSAGES=ru_RU.utf8
vadim@host3:~/tmp$ cat 1.tcl 

gets stdin s
set s [string tolower [string trim $s]]
puts stdout $s
set c [open tmp.txt w]
puts $c $s
vadim@host3:~/tmp$ echo Привет | tclsh 1.tcl ; cat tmp.txt
привет
привет
vadim@host3:~/tmp$ 
geekless ★★
()

set teg [string tolower [string trim $teg]]. Если убрать tolower (set teg [string trim $teg]) все работает отлично.

Из этого скрипта пишутся разные строки в разные файлы - проблема только здесь

а откуда берётся изначально значение $teg ? и какие кодировки у «разных файлов» ?

з.ы. встречал нечто схожее в tcl-ldap при работе с ActiveDirectory: чтобы ничего не корёжилось, приходилось дополнительно гонять строки через «encoding convertto utf-8/convertfrom utf-8», что упомянутый utf-8 везде и покругу :) пришёл к выводу что это фича взаимоотношений пакета ldap, AD и кривой конвертации UCS16LE в UTF - сделал соответсвенные обёртки и мир снова стал прекрасен :)

MKuznetsov ★★★★★
()
Ответ на: комментарий от true_admin

puts [exec locale] - абсолютно идентичен консольному:

LANG=ru_RU.utf8
LC_CTYPE="ru_RU.utf8"
LC_NUMERIC="ru_RU.utf8"
LC_TIME="ru_RU.utf8"
LC_COLLATE="ru_RU.utf8"
LC_MONETARY="ru_RU.utf8"
LC_MESSAGES="ru_RU.utf8"
LC_PAPER="ru_RU.utf8"
LC_NAME="ru_RU.utf8"
LC_ADDRESS="ru_RU.utf8"
LC_TELEPHONE="ru_RU.utf8"
LC_MEASUREMENT="ru_RU.utf8"
LC_IDENTIFICATION="ru_RU.utf8"
LC_ALL=[\code]

С env понятное дело сложнее, но тоже вроде все верно:

env(DOCUMENT_ROOT) = /var/www 
env(GATEWAY_INTERFACE) = CGI/1.1 
env(HTTP_ACCEPT) = text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 
env(HTTP_ACCEPT_ENCODING) = gzip, deflate 
env(HTTP_ACCEPT_LANGUAGE) = ru-RU,ru;q=0.9,en;q=0.8 
env(HTTP_CONNECTION) = Keep-Alive 
env(HTTP_COOKIE) = BITRIX_SM_LOGIN=admin; BITRIX_SM_UIDH=f34963b4c8f2460bbaec6223c07f69af; BITRIX_SM_SALE_UID=0 
env(HTTP_HOST) = localhost 
env(HTTP_USER_AGENT) = Opera/9.80 (X11; Linux x86_64; U; ru) Presto/2.9.168 Version/11.51 
env(LANG) = ru_RU.utf8 
env(PATH) = /usr/local/bin:/usr/bin:/bin 
env(PWD) = /var/www/sites/icengine 
env(QUERY_STRING) = pac=arts&cmd=add 
env(REMOTE_ADDR) = 127.0.0.1 
env(REMOTE_PORT) = 35813 
env(REQUEST_METHOD) = GET 
env(REQUEST_URI) = /sites/icengine/icecontrol.cgi?pac=arts&cmd=add 
env(SCRIPT_FILENAME) = /var/www/sites/icengine/icecontrol.cgi 
env(SCRIPT_NAME) = /sites/icengine/icecontrol.cgi 
env(SERVER_ADDR) = 127.0.0.1 
env(SERVER_ADMIN) = webmaster@localhost 
env(SERVER_NAME) = localhost 
env(SERVER_PORT) = 80 
env(SERVER_PROTOCOL) = HTTP/1.1 
env(SERVER_SIGNATURE) = 
Apache/2.2.16 (Ubuntu) Server at localhost Port 80
 
env(SERVER_SOFTWARE) = Apache/2.2.16 (Ubuntu) 1:wrong_key[\code]
Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

Да читаются. Все остальное отлично работает. К тому же я пробовал это и с ActiveTcl и с eTcl который вообще одним бинарником с вкомпилиными библами идет.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

ну прям даже не знаю..может таки ошибка не в TCL а в скрипте?

для полной очистки совести можешь проверить с http://jim.berlios.de/ - у него кодовая база отлична от tcl (с 0 сделана и по другому). Если ошибка и там проявится - знать судьба такая :)

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

В целом проблему можно сформулировать вот так:

cgi запускается с iso8859-1 (и переменные повидимому передаются ему в этой кодировке) и пока не используется tolower все строки как положено сохраняются в нормальном виде в файлы в utf-8. Если в скрипте врубить utf-8 все строки сохраняются покарежеными, если не врубать utf-8 то коверкаются только строки к которым применен tolower (toupper, totitle).

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

А откуда всё-таки берутся эти строки/переменные? Покажите код, который их читает, и результат «encoding system» перед его выполнением.

anonymous
()
Ответ на: комментарий от anonymous

Читаются из POST запроса с помощью ::ncgi::value

результат «encoding system»

iso8859-1

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

> Плохо то, что хотя

set env(LANG) ru_RU.UTF-8
set env(LOCALE) ru_RU.UTF-8
меняют кодировку на нужную, эффекта это не оказывает.

А какой эффект по-твоему это должно оказать?

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Не должна ломаться кодировка после to[lower|title] и должен начать работать toupper - очевидно же.

Я вообще с трудом могу понять причину проблем, если честно. В какой кодировке содержимое строковых переменных? В системной? Почему тогда string tolower ломает кодировку? Если она может работать только с utf-8, почему тогда ничто не изменяем перекодировка в utf-8 tolower перекодировка из utf-8?

И наконец почему этот код выводит 3 одинаковые строки:

set tegs [::lcgi::value tegs]
puts $tegs
puts [encoding convertfrom $tegs]
puts [encoding convertto $tegs]

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

> Не должна ломаться кодировка после to[lower|title] и должен начать работать toupper - очевидно же.

Ожидать такого - очевидная же глупость.

Переменные окружения учитываются как правило при инициализации процесса. Так что расчитывать тебе надо на то, что после set env() дочерние процессы будут использовать эти значения. Текущему процессу как бы пофик.

LamerOk ★★★★★
()
Ответ на: комментарий от Suntechnic

В какой кодировке содержимое строковых переменных? В системной?

Считай, что в своей собственной:)

set text [encoding convertfrom кодировка-в-которой-был-текст [encoding convertto [encoding system] $твой_текст]]

puts [string tolower $text]
puts [string toupper $text]

так работает?

anonymous
()
Ответ на: комментарий от anonymous

Нет. Я наверное уже попробовал все сочетания кодировок... ни одна не помогает прочитать текст после tolower - надо разбираться как он работает и чего ему вообще надо...

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

А как апач заставить запусткать скрипи в utf и в нем же передавать данные?

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

надо разбираться как он работает и чего ему вообще надо...

tolower не причем, если ввод-вывод настроен на iso8859-1.

encoding system utf-8

foreach chanId [file channels] {
    fconfigure $chanId -encoding utf-8
}
anonymous
()
Ответ на: комментарий от anonymous

Почему в остальных случаях работает нормально если tolower не причем? Почему нормально работает trim, range, index, map? Ведь после других операций со строками все сохраняется нормально, и все великолепно сохраняется в utf-8.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Потому что в отличии от этих команд работа tolower зависит от кодировки.

Выражусь точнее. От того, правильно ли перекодирована строка.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.