存档

‘Linux’ 分类的存档

使用 screen 命令的一些小技巧

2010年7月22日 Solrex Yang 5 条评论

由于工作环境的问题,最近越来越感觉到 screen 命令的可贵,下面总结一点使用 screen 命令的小技巧。

最常用的参数组合:

screen -ls // 列出已有的 screen
screen -D -R // 进入指定的 screen 名,如果没有,则以该名称创建 screen

由于很常用,我把这两个命令取了个 alias:

alias sl='screen -ls'
alias sr='screen -D -R'

除了命令之外,还有快捷键 Ctrl+ac 创建 screen;Ctrl+aa 在两个 screen 之间相互切换;Ctrl+ad 从 screen 中 detach;Ctrl+a数字,跳转到数字指代的 screen。

在 screen 最下方显示状态栏,状态栏包括已经打开的 screen 标签列表,当前的 screen 和时间。其中在 screen 标签处显示该 screen 所处的目录名。显示 screen 所处的目录名这一点实现起来要困难一些,首先得修改 .bashrc,加入 screen term 对应的信息

case $TERM in
    screen*)
        # This is the escape sequence ESC k \w ESC
        # Use current dir as the title
        SCREENTITLE='\[\ek\W\e\\\]'
        PS1="${SCREENTITLE}${PS1}"
        ;;
    *)
        ;;
esac

然后 . 或者 source 一下,再修改 screen 的配置文件,添加状态栏,在 .screenrc 中添加:

caption always '%{=b cw}%-w%{=rb db}%>%n %t%{-}%+w%{-b}%< %{= kG}%-=%D %c%{-}'
shelltitle '$ |bash'

最终效果为:

GNU Screen 多标签状态栏

删除 MBR 引发的诡异问题

2010年6月14日 Solrex Yang 7 条评论

我要跟女友交换一下笔记本电脑,她不常用 Linux,而我的 Ubuntu 分区占了好几十 G 空间,因此我想还是删了再给她吧。

我的电脑有两个系统:Windows Server 2008 和 Ubuntu 10.04。按照惯常的思维,删除 Ubuntu 只需要先格式化 MBR,然后删除 Ubuntu 分区即可。因为手头没有 DOS 启动盘,我想到一键恢复的硬盘版是带 DOS 工具的,就在 Windows 下装了个一键恢复硬盘版,然后进 DOS 命令行 “fdisk /mbr”。

可谁知道做完这些之后,MBR 是清掉了,但系统无法启动了,提示消息是这样的:

Windows 未能将启动原因可能是最近更改了硬件或软件
文件:\Windows\system32\winload.exe
状态:0xc000000e
信息:无法加载所选项,因为应用程序丢失或损坏。
...

然后我就傻眼了,从来没有遇到过这种情况呀!搜索了一番之后,才明白了这是什么意思。

Windows Vista 之后的系统,不再使用 boot.ini 保存启动菜单,而是使用一种叫做 BCD(Boot Configuration Data)机制来管理启动菜单,其默认的配置文件是活动分区(一般是 C:\)的 \Boot\BCD。简单的来说,可以将 \Boot\BCD 文件看成是 GRUB 的 menu.lst(grub.conf)文件,里面储存着系统装载程序的路径和参数等。

在我这里,出现上面问题的原因是 BCD 每项记录中的 device 选项被“一键恢复硬盘版”改成了 unknown,这样启动程序不知道到哪里去找系统的装载程序,自然也就无法启动了。使用 bcdedit /store C:\Boot\BCD 可以查看系统的 BCD 每项记录。(较为诡异的是,在没有删除 MBR 之前,我是如何进入到启动项里的?)

我用的解决方法是把所有默认启动项中的 unknown 改成了 boot。还得依靠工具,使用 WinPE U 盘(DOS 启动盘未尝试)启动,进入 C:\Windows\System32\,执行 bcdedit 命令:

bcdedit /store C:\Boot\BCD /set {default} osdevice boot
bcdedit /store C:\Boot\BCD /set {default} device boot
bcdedit /store C:\Boot\BCD /set {default} detecthal 1

然后就可以启动进入 Windows 了。

分类: Linux 标签: , , , ,

Fix Black Screen After Boot Problem of Ubuntu 9.10 on D630

2009年11月3日 Solrex Yang 6 条评论

Platform: Dell Latitude D630, Nvidia NVS 135M, Intel CPU, Ubuntu 9.10

Problem:

1. Boot from livecd, select install. After a glowing ubuntu Symbol, screen shows nothing, even no CLI.

2. After installation with "text mode", boot from HD. After a glowing ubuntu Symbol, screen shows nothing, even no CLI.

Solution:

I am not very sure whether this problem is caused by the NV 185 driver(nvidia-glx-185). Installing or removing this package gave no help. I googled a lot, found many people encountered the same problem. However, no answer could work on my laptop. Then I tried to install NV driver manually...it works! So, here is the fix:

1. When you get the GRUB boot menu screen, press 'e' to edit the fist entry. Add a word 'single' after 'linux /boot/vmlinuz..... quiet splash', then press 'Ctrl+x' to boot. (I cannot enable networking in recovery mode, so I tried with the single mode.)

2. Select the 'netroot' entry. You will get a root command line with network support.

3. Download the latest NV driver for linux (2010-11-3):

# wget http://us.download.nvidia.com/XFree86/Linux-x86/190.42/NVIDIA-Linux-x86-190.42-pkg1.run

[You can visit http://www.nvidia.com/object/unix.html for the latest NV driver.]

4. Install development tools to build NV driver on you os.

# apt-get update
# apt-get install build-essential

5. Install the NV driver:

# chmod u+x NVIDIA-Linux-x86-190.42-pkg1.run
# ./NVIDIA-Linux-x86-190.42-pkg1.run

6. Reboot.

If you are using a livecd, please use the "text mode" to install Ubuntu 9.10. After installation, try the solution above.

Ubuntu 9.10 启动后黑屏的解决方法

平台: Dell Latitude D630, Nvidia NVS 135M, Intel CPU, Ubuntu 9.10

问题描述:

1. 从 livecd 启动后,选择安装,在白色 Ubuntu 图标闪烁结束之后,无任何屏显,连命令行都没有。

2. 用文本模式安装完成后,从硬盘启动,在白色 Ubuntu 图标闪烁结束之后,无任何屏显,连命令行都没有。

解决方法:

我不太清楚是不是 NV 的 185 驱动有问题(nvidia-glx-185),安装或者删除它对状况没有任何帮助。我搜索了一下,发现很多人遇到和我类似的问题,不过没有任何解决方法可以在我的电脑上工作。无奈下我尝试手动安装了一下 NV 的最新驱动——居然解决了!下面是我的解决方法:

1. 当你进入 grub 启动菜单选择屏幕时,在第一条上按 e 进入编辑状态,在 'linux /boot/vmlinuz..... quiet splash' 这一行最后添加一个单词 single,然后按 Ctrl+x 启动。其实 recovery mode 能做类似的事,但是 9.10 的 recovery mode 好像不能启动网络,所以只好自己进入 single 模式了。

2. 启动后选择 'netroot' 选项,进入带网络的 root 命令行。

3. 下载最新的 NV 驱动(2010-11-3):

# wget http://us.download.nvidia.com/XFree86/Linux-x86/190.42/NVIDIA-Linux-x86-190.42-pkg1.run

[你可以先访问 http://www.nvidia.com/object/unix.html 查看 NV 最新驱动的地址。]

4. 安装编译 NV 驱动需要的编译工具:

# apt-get update
# apt-get install build-essential

5. 安装 NV 驱动:

# chmod u+x NVIDIA-Linux-x86-190.42-pkg1.run
# ./NVIDIA-Linux-x86-190.42-pkg1.run

6. 重启

如果您使用 livecd 安装 Ubuntu 9.10 的话,您应该选择 "text mode" 进行安装。成功安装完成后,仍然遇到黑屏问题,请尝试上述方法。

分类: Linux 标签: , , , ,

SVN 技巧:GUI 版本比较和可执行属性

2009年8月28日 Solrex Yang 1 条评论

我曾经在《使用 kdiff3 进行 svn 版本比较》中介绍了为什么以及如何使用 kdiff3 或者 meld 等 GUI 比较工具进行 SVN 版本比较。但这样做有个小问题,就是如果设置了 GUI 工具作为比较工具,那么就没办法输出 diff 文件,而且每次都要关掉窗口才会出现下一个文件,就无法比较多个文件了。所以我觉得下面这种做法会更好一些:

$ more svndiff
#!/bin/bash
sed -i -e 's/^# diff-cmd.*$/diff-cmd=meld/' ~/.subversion/config
svn diff
sed -i -e 's/^diff-cmd.*$/# diff-cmd = meld/' ~/.subversion/config

其实就是用一个脚本 svndiff 来做 GUI 比较的工作。svndiff 执行时首先将 svn 配置文件中的比较工具改为 meld,然后进行比较,比较完后再将修改注释掉,这样就不会影响正常 svn diff 的功能。这样一来,svndiff 是 GUI diff,svn diff 就是命令行 diff。

设置文件可执行属性对 Windows 用户来说可能没什么用,可是对 Linux 用户来说用处就大了。没人希望每次一 update,就要重新对需要执行的脚本 chmod 一下。svn 修改文件可执行属性的命令太长了,我老记不住,所以放在这里做个笔记吧:

svn propset svn:executable ON filename

分类: Linux, Programming 标签: , , , ,

在 Ubuntu 9.04 上安装 Kscope

2009年7月8日 Solrex Yang 5 条评论

Kscope 是我很喜欢的 Linux 平台上的代码查看工具,因为我不会用 Emacs,vim + ctags 又用得不熟,看看小程序还可以,看大项目就傻眼了。以前也尝试过 Source-Navigator(这个项目N年没更新,06年时候我装都装不上,08年底居然又复活了,有空了再去试试)、Eclipse、Kdevelop、CodeBlocks,总之都没有 Kscope 用着最舒服。Kscope 让我欣赏的特点主要有:

1. 它号称是代码编辑环境(source-editing environment),而不是IDE。我不用在建立 Kscope 项目时烦心地去选择项目类型、编译器、编译选项等等。编译我有 Makefile,我就是找个工具看看代码,用得着那么麻烦吗。 建立 Kscope 项目时只需要干两件事:选择项目名、项目保存地址和添加源文件。

2. 它不会在源文件目录下建立一堆乱七八糟的文件,影响市容。我记得 Eclipse、CodeBlocks 等都会把项目信息保存在源文件目录下,而 Kscope 的项目保存位置可以自己选,比如我一般都保存在 workspace/kscope 目录下面,这样对要查看的源文件目录没有任何影响。因此 Kscope 的项目和源文件基本没关系,我可以添加任何位置的源文件到某个项目中去。

3. 它不会去读非指定类型的文件。这是针对 Eclipse 来说的,每次在 Eclipse 项目中搜索时,一堆 .svn 目录中文件的结果让我感觉非常闹心,两年没用不知道现在的 Eclipse 是不是更智能点儿了,但是 Eclipse 改不了的毛病就是慢和吃内存。

4. 它支持代码查看的基本功能。其实我最常用的也就那么几个功能:语法高亮、同时打开多文件、整个项目中搜索字符串、查找函数定义位置和引用、项目文件列表+搜索。在这些条上据说 Windows 下的 SourceInsight 做得更好,但我没用过没有发言权。

简而言之,Kscope 与其它工具比就是快、简单、省心。但是时代在变革呀,转眼到了 KDE4 的时代,而 Kscope 仍然停留在 KDE3.5 上。现在的 Ubuntu 9.04 的依赖关系里,居然已经撤掉了 Kscope,在 9.04 上 sudo apt-get install kscope,会得到这样的消息:E: Couldn't find package kscope,真是让人丧气。

其实 Kscope 之所以不能安装,主要原因是它依赖于 Kate 的两个库:libkateinterfaces.so.0 和 libkateinterfaces.so.0,只需要从 KDE3.5 的 Kate 中提取出来这两个库安装到系统中后,Kscope 就可以正常运行了。Ubuntu 9.04 的依赖关系中虽然找不到 Kscope,但是 Ubuntu 的软件仓库中还有 Kscope 的包,我们可以手动下载安装。下面这个脚本的功能就是自动安装 kscope 到 Ubuntu 9.04,稍微修改一下也可以用于在其它 KDE4 桌面系统中安装 Kscope,或者解决 Kscope 无法运行的问题。您也可以从这里下载到该脚本:

#!/bin/bash
# This script helps you install Kscope on Ubuntu 9.04.
# You can also use it to fix "Kscope doesn't run in KDE4" bug.

echo "Determining machine hardware name... "
MACHINE=`uname -m`
case "$MACHINE" in
  i386 | i586 | i686)
    ARCH="i386"
    ;;
  x86_64)
    ARCH="amd64"
    ;;
  *)
    ARCH="i386"
    ;;
esac

# If Kscope is not installed, install it.
which kscope &> /dev/null
if [ $? -ne 0 ]; then
  echo "Installing kscope..."
  sudo apt-get install kscope || \
  wget http://archive.ubuntu.com/ubuntu/pool/universe/k/kscope/kscope_1.6.0-1_${ARCH}.deb && \
  sudo dpkg -i kscope_*.deb || \
  sudo apt-get -fy install || \
  echo "Oops, some error happens..."
fi

kscope -v &> /dev/null
if [ $? -eq 0 ]; then
  echo "Kscope works fine."
  exit
fi

echo "Downloading KDE3 libraries needed by kscope..."
wget http://ftp.debian.org/debian/pool/main/k/kdebase/kate_3.5.9.dfsg.1-6_${ARCH}.deb
dpkg -x kate_3*.deb kate

echo "Installing KDE3 libraries..."
sudo cp kate/usr/lib/libkateinterfaces.so.0.0.0 /usr/local/lib/
sudo cp kate/usr/lib/libkateutils.so.0.0.0 /usr/local/lib
sudo ln -s /usr/local/lib/libkateinterfaces.so.0.0.0 /usr/local/lib/libkateinterfaces.so.0
sudo ln -s /usr/local/lib/libkateutils.so.0.0.0 /usr/local/lib/libkateutils.so.0
sudo ldconfig

echo "Finished."

分类: Linux 标签: , , , , ,

Linux 下 Firefox 变身 Google Chrome

2009年6月20日 Solrex Yang 9 条评论

几乎可以达到以假乱真的效果,屏幕截图请看:

Linux 下 Firefox 变身 Chrome

要求:
1. KDE 4 ---> Gnome 的窗口无法隐藏标题栏,影响变身效果(这也是目前我觉得 KDE 更好玩的原因之一)
2. Firefox 3.5 以上 ---> 3.5 以下无法使用 Chromifox Extreme 主题,只能使用 Basic Chromifox Extreme 主题
3. Chromifox Companion 扩展 ---> 配合 Chromifox Extreme 主题修改工具栏图标
4. Hide Menubar 扩展 ---> 隐藏菜单栏,可以使用 alt 呼出

步骤:
1. 安装 Firefox 3.5。下载 tar.bz 包之后解压到 /opt 目录下,比如目录名为 /opt/firefox,修改 /usr/bin/firefox 软链接到 /opt/firefox/firefox。
2. 安装 Flash 插件。在 /opt/firefox/plugins 目录下建立软链接 libflashplayer.so 到 /usr/lib/flashplugin-installer/libflashplayer.so。
3. 打开 Firefox,查看版本是否 3.5,安装 Chromifox Extreme 主题
4. 安装 Chromifox Companion 扩展
5. 安装 Hide Menubar 扩展
6. 设置隐藏标题栏。右击标题栏,Advanced->Special Application Settings->Preferences->No border,下拉选择 Apply Initially,勾上后面的复选框。
7. 重启 Firefox。

Update:在 Ubuntu 下安装 Google Chrome (开发者版)和 Google Earth

$ echo "deb http://dl.google.com/linux/deb/ stable main" > google-chrome.list
$ sudo mv google-chrome.list /etc/apt/sources.list.d/
$ wget https://dl-ssl.google.com/linux/linux_signing_key.pub -O - | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install google-chrome googleearth

遗憾的是,Chrome4Linux 目前还不支持中文。

分类: Linux 标签: , , , , ,

Solrex Linux Cheatsheet

2009年6月7日 Solrex Yang 14 条评论

Cheatsheet:原意是考试的时候带的小抄,所以说是 cheat(作弊) sheet。在计算机科学领域里,主要是指记录一些难记命令或者操作的快查表,有时候和 quick reference card 意思相同,中文或者可以翻译成:命令速查表?

由于很少看到中文的比较完善的 Cheatsheet,我想,做一个这样的 Cheatsheet 应该挺不错。所以我就我自己使用 Linux 的经验,打算整理出来一个中文的 Linux Cheatsheet。目前放出零点零一版,您可以到这里下载,目前的具体状况如下图所示:

Solrex Linux Cheatsheet

这个 Cheatsheet 包含两个文件,一个 pdf 文档,一个 odt 文档。如果您想帮助我完善它,您可以将您修改过的 odt 文档发送给我。如果您的建议被采纳,您的名字(或代号)和链接将被添加到该页面的“感谢”一栏中,谢谢。

最后重复,Solrex Linux Cheatsheet 的主页在:http://share.solrex.org/cheatsheet/slc/

PS: 其实我昨天就想发这篇博客了,但是两天来我所在的北京网通 ADSL 网络访问我的博客一直有问题,不排除被封的危险。如果您想继续关注本博客,推荐您使用 Google Reader 或者抓虾等在线 RSS 订阅器订阅本博客的 RSS,这样被封后至少您能看到本博客的文章更新。

分类: Linux 标签: , ,

使用 kdiff3 进行 svn 版本比较

2009年5月27日 Solrex Yang 6 条评论

svn diff 命令的效果总的来说还是不错的。因为它是基于行的比较,在比较格式规范的程序代码文件时候也足够了,尤其是每行不超过 termial 宽度的时候。但是在比较那些单行长度比较长的文件时,比如 HTML, TEX 等,仅仅修改一个字母也会引起两行不同,用 svn diff 查看被修改的地方时就比较痛苦了。

Linux 下有一些比较好的比较程序,比如 kdiff3, gdiff, vimdiff 等,kdiff3 可以用不同颜色显示两个文档中不同的行、字符,算是比较理想的比较程序。我们可以拿它来替换掉 svn diff 默认的比较程序。

很显然这种需求别人也会有,所以早就有高手解决了这样的问题,您可以从这里下载一个 bash 脚本,将其重命名为 svndiffwrapper,加上可执行权限放到一个可执行路径(比如 /usr/bin/)下。然后修改您的 ~/.subversion/config 文件,找到 diff-cmd,修改为如下所示:

### Set diff-cmd to the absolute path of your 'diff' program.
###   This will override the compile-time default, which is to use
###   Subversion's internal diffimplementation.
diff-cmd = svndiffwrapper
### Set diff3-cmd to the absolute path of your 'diff3' program.
###   This will override the compile-time default, which is to use
###   Subversion's internal diff3 implementation.
diff3-cmd = svndiffwrapper

这样,当您再执行 svn diff 的时候,svn 会默认调用 kdiff3 进行文件比较。由于 kdiff3 是 GUI 程序,所以文件比较将会是一个一个进行的,关掉第一个文件比较的 kdiff3 窗口,才会显示第二个文件的比较窗口。

网友 sleetdrop 评论指出,如果使用基于 Python 的 Meld 作为 GUI 比较工具,那么不需要任何 wrapper,只要修改上述配置为:

diff-cmd = meld

即可。不可否认,这比 kdiff3 简便了不少,而且 meld 还支持在比较时编辑,这也是一个很大的优点。

分类: Linux 标签: , , ,

vasprintf 会将空间分配到栈上吗?

2009年5月23日 Solrex Yang 11 条评论

由于提交过几次 Linux Fetion 的 bug 和 patch,Linux Fetion 的开发者邀请我加入了 Linux Fetion GUI 的维护者团队中。

昨天晚上和今天下午,我和邓东东(DDD)一直在调试一个 Linux Fetion 在 64 位电脑上的段错误 BUG。这是一个非常奇怪的 BUG,其表现为在 64 位电脑上(Ubuntu 9.04)运行 Linux Fetion 在登录成功后会经常出现 Segmentation Fault。DDD 确定该 BUG 存在于 Libfetion 库中,并且和读取联系人信息的函数有关。Libfetion 论坛上一直有人抱怨类似问题,但是在 DDD 的 64 位虚拟机上却无法重现此 BUG(他的 libc 是 2.7 版本的)。

由于 DDD 仍然不愿意公开 libfetion 库的源代码,我只好等每次他修改库文件之后发给我再调试。经过了好几个小时的努力,今天下午我发现,该 BUG 的主要成因非常有可能是:子函数中本应被动态分配到堆(heap)上的空间被分配(或误写)到了栈(stack)上,子函数返回调用者之后指向子函数栈内容的指针非法。

由于该动态分配的空间是使用 vasprintf 自动分配的,从 DDD 给我的部分代码来看指针传递出问题的可能性不大。那么我想,是不是 vasprintf 函数并不能保证动态分配的空间在 heap 上呢?希望对此有了解的朋友指点一下,谢谢!

$ uname -a
Linux Slytherin 2.6.28-12-generic #43-Ubuntu SMP Fri May 1 19:31:32 UTC 2009 x86_64 GNU/Linux
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.3-5ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
$ ll /lib/libc.so.6
lrwxrwxrwx 1 root root 11 2009-04-13 10:26 /lib/libc.so.6 -> libc-2.9.so

PS:我在写这篇博文过程中搜索了一下 Wikipedia,发现这样一段话:

int asprintf(char **ret, const char *format, ...)

asprintf automatically allocates enough memory to hold the final string. It sets *ret to a pointer to the resulting string, or to an undefined value if an error occurred (GLibc is notable in being the only implementation that doesn't always set *ret to NULL on error).

那么是不是分配失败导致了错误的发生呢?但是如果分配失败,为什么子函数返回前的指针的确指向一段在栈上的字符串呢?

跨平台音乐播放软件 Songbird

2009年5月17日 Solrex Yang 9 条评论

Songbird 是一款开源音乐播放软件,目前可以支持在 Windows, Linux 和 Mac 操作系统上运行。从我的角度来看,它有几大特性:(1)支持 iPod——对我来说没诱惑,我又没有 iPod;(2)类 iTunes 界面,这一点我还是很欣赏的,管理音乐比较方便;(3)内嵌浏览器,用某篇文章的话说就是:“如果iTunes和Firefox来一场甜蜜的网络性爱,他们产下的卵就是Songbird。”虽然形同鸡肋,不过也蛮有趣的;(4)支持类似于 Firefox 的插件功能,这将会是 Songbird 的杀手锏;(5)支持大部分中文歌曲 ID3 标签——这一点使我不得不喜欢它,下面我还会说到;(6)可用插件支持歌词显示。

总的来说,Songbird 吸引我的主要原因是后两条,因为我很难在 Linux 下找到实现这两条的播放软件,但是这后两条特性又貌似不那么完全。本地化、本地化,Linux 的本地化一直是一个问题,再加上像我这样的“事儿妈”喜欢在 en_US.UTF-8 的 LOCALE 下追求中文使用的无障碍,使得问题更糟糕。Linux 下的经典播放软件 xmms, RhythmBox, Amarok,无一例外都被中文 ID3 标签显示问题打败(或者说我不知道如何配置?)。

Songbird 让我看到了一丝希望。我目前歌曲库中所有歌曲都是从 Google Music 下载的,乍一装上 Songbird 运行后,我发现它居然能识别出大部分歌曲的 ID3 信息(Windows 和 Linux 平台下效果是一样的),不过仍然有乱码存在。我想可能是 ID3 标签自身问题,于是到 Windows 下用千千静听编辑了一下这些显示为乱码的歌曲信息。经过多次尝试,发现用千千静听将 ID3 信息先写入为 ID3v1,然后再重新以 UTF-16 格式写入为 ID3v1 & ID3v2 貌似可以解决 Songbird 的乱码问题,至少我的歌曲库已经没有乱码了。

这个乱码解决方案的重要之处在于:Windows Explorer 支持该方案,也意味着大部分 MP3 音乐播放器(随身听)支持该方案。不像通常为使 Linux 下的播放软件(比如 Amarok)支持 ID3 标签,要强行将 mp3 文件的 ID3 标签转换为 UTF-8 编码,这样会造成大部分 mp3 随身听和 Windows Explorer 无法显示歌曲信息。(插一句:在我使用过的 mp3 里,只有魅族 Miniplayer(M6) 支持 UTF-8 格式的 ID3 标签和 UTF-8 格式的 txt 文档,这也是我对魅族这间公司有很大好感的原因之一。)

Songbird 的歌词插件也很奇怪,貌似它只支持内嵌于 ID3 标签中的歌词,而且没有时间轴,还好 Google Music 的歌曲大部分内嵌有歌词。不知道存不存在可以从外部文件读取歌词并且以时间轴显示的插件?

关于 ID3 标签,我还有一些疑问,下面列出来,希望对此有了解的朋友能够指点一二。

1. 网上讨论 Linux ID3 标签编码问题时经常会说 ID3 标签的编码是 GBK, BIG5 所以造成了乱码问题。但 Wikipedia 上说,ID3v1 只支持 ISO-8859-1,ID3v2.1 增加了 UTF-16 支持,ID3v2.4 增加了 UTF-8 支持,貌似 ID3 标签根本没有 GBK 编码这一说。那么乱码问题到底和 GBK 有关系吗?

Li Fanxi 网友的重要评论:ID3v1只支持ISO-8859-1,不过很多传统的软件,比如WinAMP或Tag&Rename,都会用System Code Page去存放非ISO-8859-1中的字符。对于CP936,自然就是GB2312了。一些严格符合标准的软件如果没有考虑到这个问题,就会出现乱码。

2. 这篇疑似 Amarok 开发人员的博客中说:“(我们限制自动检测编码功能仅检测 ID3v1 )基于这样的假设:所有的 ID3v2 使用的是 UTF-8 编码,所有的 ID3v1 使用的是非 UTF-8 编码。”但是要知道大部分中文 MP3 歌曲使用的是 ID3v2.3,根本不支持 UTF-8。那是否能得出这样的结论:Amarok 乱码问题是因为 Amarok 不支持 ID3v2 标准,而不是 Windows Explorer 和其他 mp3 播放器厂家不支持标准?那么我想,有了 Songbird,是放弃 Amarok 的时候了。

Li Fanxi 网友的重要评论:ID3v2.3不支持UTF-8,如果用UTF-8存ID3v2.3 Tag可以看成是软件的Bug,我不太确定有多少软件会这么做。

3. 为什么某些同样是 ID3v2.3 编码的 MP3,Windows Explorer 和千千静听能读取正确,Songbird 中却有可能显示为乱码呢?

Li Fanxi 网友的重要评论:这个问题还是要具体问题再具体分析,可以用软件分析一下这个文件中倒底存了多少种Tag,一个文件中可以同时存在几种版本的Tag,比如ID3v1、ID3v2、APE,不同的软件可能对不同的Tag的识别优先级不一样,导致显示结果不一样。

虽然我天天在Linux下工作,不过管理Tag我还是wine一个Windows下的Mp3tag来用,因为以前在Windows下用惯了,而且我也在维护这个软件的简体中文语言文件。这个软件Usability不算好,不过功能很强,适合对MP3 Tag管理有比较高要求的朋友用用。http://www.mp3tag.de/en

对于解决乱码MP3的问题,我用Mp3tag的方案是先对用System Code Page存放的Tag做一次Convert Codepage的Action。然后把MP3 Tag清除动作设成清除所有,写入动作设成只写入ID3v2.3 UTF-16,然后对所有的文件做一次Ctrl+X再Ctrl+V。世界就清静了。

PS: 一定要试试 Songbird 的 MashTape 插件,很好很强大!