控制台中的西里尔字母问题

4 投票
4 回答
4541 浏览
提问于 2025-04-16 09:07

抱歉我的英语不好。这段代码是用Ruby写的。

s = "мистика"

`touch #{s}`
`cat #{s}`
`cat < #{s}`

有人能告诉我为什么这段代码会出错吗?错误信息是:

sh: cannot open ми�тика: No such file

但是这段代码运行得很好:

s = "работает" 
`touch #{s}` 
`cat #{s}` 
`cat < #{s}` 

问题只出现在俄文字符 'с' 和符号 '<' 的时候。

woto@woto-work:/tmp$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

woto@woto-work:/tmp$ ruby -v 
ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux] 

woto@woto-work:/tmp$ uname -a 
Linux woto-work 2.6.32-26-generic #48-Ubuntu SMP Wed Nov 24 10:14:11 
UTC 2010 x86_64 GNU/Linux 

woto@woto-work:/tmp$ lsb_release -a 
No LSB modules are available. 
Distributor ID: Ubuntu 
Description:    Ubuntu 10.04.1 LTS 
Release:        10.04 
Codename:       lucid 

另一个例子

也许这个例子对理解我的问题会有帮助。

woto@woto-work:~/rails/avtorif$ touch мистика
woto@woto-work:~/rails/avtorif$ ruby -e "`cat < мистика`"
woto@woto-work:~/rails/avtorif$ ruby -e '`cat < мистика`'
sh: cannot open ми�тика: No such file

4 个回答

0

在你给出的每个例子中,你都是在执行一个命令行指令。首先,我建议你直接在命令行中输入这个指令,看看它是否能正常运行:

touch мистика
cat мистика
cat < мистика

如果你在命令行中遇到错误,可能有两个原因:要么是命令行不理解字符编码,要么是文件名需要加上引号,以便正确区分。

Ruby 1.9可以理解字符集编码,而Ruby 1.8则不行。你需要查一下你的命令行环境使用的是什么字符编码。确定之后,你就可以把命令写成普通的字符串:

touch = "touch #{s}".force_encoding("UTF-8") ## or whatever encoding you need

然后执行这个命令:

`#{touch}`

我认为Ruby 1.9的默认编码是UTF-8。而Ruby 1.8没有编码的概念,字符串只是字节的数组。不幸的是,并不是所有软件都能理解unicode或字符编码的概念(就像Ruby 1.8一样)。在这种情况下,系统会使用默认的编码。我怀疑你的命令行环境可能就是这种软件之一。

0

这个方法对我有效,你试过这样做吗?

s="мистика"
touch $s

在bash中,引用一个变量时,要在前面加上美元符号。

1

这是一个在 dash 中的错误,dash 是 Debian 默认使用的一个命令行工具(也就是 /bin/sh 实际上指向 /bin/dash;而 Python 的 os.system 也会用到 sh。Ruby 可能也会用到 sh)。dash 无法正确处理 8 位文本,包括 UTF-8 编码。为了绕过这个问题,你可以把它换成 bash

sudo dpkg-reconfigure dash

然后选择“否”。这样系统就会把 bash 作为 /bin/sh 的命令行工具,这样就能处理 UTF-8 了。

撰写回答