分类目录归档:IT

如何正确在 Windows 10 上关联一个新的扩展名

Windows 10 这个 UWP 的逻辑太垃圾了。

在以前版本的 Windows 中,我们如果想使用一个程序打开一个从来没注册过的扩展名,通常直接右键属性就可以完成。但是在 Windows 10 上,这个做法就失效了。例如,我需要使用 XnView MP 打开 .webp 文件,尽管我已经把 XnView 注册为默认的图像查看器,但是并不是所有的图像格式都被关联到了它上面(这个原因说实话也很简单,Windows 怎么知道什么格式的东西是”图像“,它也不可能维护一个世界上所有图像格式的列表),比如 .webp 格式就没有被关联。使用右键打开方式强行关联到 XnView 以后,就会有一个新的问题,在双击的时候,XnView 是打开了,但是没有打开对应的文件。

因此,还是需要找注册表解决。

在我们使用右键打开方式关联 .webp 格式以后,注册表的情况是这样的:

可以看到,创建了 .webp 这个扩展名,并且指向 .webp_auto_file,然后指向 XnView 执行文件,但是注意没有带任何参数,因此 XnView 无从知道要打开什么文件。

那么这时候可行的解决方法就是,更改 command 的值,在路径后加上 ”%1“ 这个参数。

或者也可以把这两个项都删掉,之后通过命令行解决:

ftype extfile="C:\Program Files (x86)\YourProgram.exe" "%1"
assoc .ext=extfile

extfile 可以随便更改,只是描述文件的名字,然后将 .ext 指向这个项就可以了。

之后重启,且需要在 explorer 里面再在右键中打开方式处设置一下关联,关联到刚刚选择的程序,就能正常双击打开了。注意这步一定要做,否则似乎并不会很快生效。

Reference:
https://superuser.com/questions/1080453/adding-or-registering-a-file-type-so-it-can-be-associated-with-an-application

关于 OPAL Drive 和 BitLocker 关系的理解

起因是这样的,美帝良心想这个 X1 Carbon 的官网上在调整 SSD 配置的时候,从 256G 加到 1T 需要增加 591USD,即使算上 45%off 的折扣也要 200 多刀。然而一个 SN750 1T 在美亚不过也才 200 刀,在官网加 SSD 就相当不合算了。

但是我注意到了一点,联想官网上对 SSD 的描述是 OPAL,也就是符合 OPAL 标准的自加密 SSD (Self-Encrypting Drive,SED),机器到手以后也默认开启了 BitLocker。在我的记忆中,BitLocker 是一个纯软件的实现,那么这里 SSD 的自加密和 BitLocker 的关系是什么呢?

查了一圈资料以后发现,BitLocker 存在硬件和软件两种实现方式。在检测到硬盘控制器支持硬件加密的时候,Windows 会直接使用该功能,且不对数据进行任何处理的方式就写入磁盘,由主控完成加密。如果主控不支持加密,则使用软件实现。具体的实现方式可以通过 manage-bde 这个命令查看:

如果是软件实现,那么在 Encryption Method 下就会显示类似于 XTS-AES 128 这样的字眼。在一些比较老的版本上可能只是 AES 128。

如果是启用了硬件加密特性,那么应该是这样:

显示为 Hardware Encryption。

如果是官网购买的 OPAL Drive,那么应该是可以显示为 Hardware Encryption 的,如果是自行购买的 SN700(官网是 SN720,也就是前者的 OEM 版本),那么就是软件加密。

如果没有关闭 BitLocker 就取下了硬盘,在数据可以抹掉的情况下,理论上有两种方法可以解开。一个是使用 BitLocker 恢复密钥,这个会自动同步到自己的 Microsoft Account 上,可以看这里。或者也可以考虑直接使用命令抹掉数据并重新生成密钥,这个可以看 ArchWiki 的详细讲解。

Reference:
https://wiki.archlinux.org/index.php/Self-Encrypting_Drives
https://helgeklein.com/blog/2015/01/how-to-enable-bitlocker-hardware-encryption-with-ssd/
https://support.microsoft.com/en-us/help/4026181/windows-10-find-my-bitlocker-recovery-key
https://howtogeek.com/fyi/you-cant-trust-bitlocker-to-encrypt-your-ssd-on-windows-10/
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/ADV180028

如何压缩 VirtualBox 的 vdi 虚拟磁盘

VMware 的虚拟磁盘管理界面上有两个功能,一个是整理磁盘碎片,另一个是回收未使用的空间。这两个功能配合使用,就可以清理掉虚拟磁盘映像文件里面已经删除了的文件依然占用的空间。然而,辣鸡如 VirtualBox 并没有提供这两个功能,需要手动进行未使用空间填零和压缩磁盘映像文件两个步骤。

首先需要确保使用的映像文件格式是动态分配,这样才有压缩的可能性。

如果是 Windows 客户机,那么首先进行磁盘碎片整理,完成之后,下载 sdelete 工具,使用例如:

sdelete.exe c: -z

这样的命令对 C 盘完成填 0 操作。

如果是 Linux 客户机,那么需要使用 zerofree 命令完成这个操作。由于该命令不能在盘符分区已经挂载的情况下工作,且最近版本的 Ubuntu 在 Recovery 模式下也会挂载所有的盘符,因此如果要进行这个操作,需要使用一个 Live CD 进入系统。安装 zerofree 之后,运行:

# zerofree -v /dev/sda1

这样的命令对 /dev/sda1 进行填 0 操作,之后就可以进行压缩了。

压缩的操作我们需要使用 VBoxManage 命令:

VBoxManage modifymedium disk "/path/to/disk.vdi" --compact

在 Windows 下可能需要手动在 VirtualBox 安装路径下找到 VBoxManage.exe 进行操作。之后就压缩成功了。

迁移一个 MediaWiki

讲道理,迁移这玩意比迁移一个 WordPress 麻烦多了。

以下记录仅作为记录,因为迁移配置的环境实在不是很通用。

简单来说,我需要做的一件事是在两台我都没有 root 权限的服务器上迁移一个 MediaWiki 站点。理论上来说,按照官方提供的文档可以很简单地完成这件事,但是其中有一些细节还是需要注意。

从一个比较 high-level 的层面上来说,迁移需要做三件事,导出数据库、移动文件、导入数据库。很简单对吧,然而在两边的 web 环境不一致且不可能完全自己重装的时候,这个问题就不那么简单了。

遇到的第一个问题是,目标环境中的 PHP 没有安装 SQLite 模块,这就意味着必须使用 MySQL 作为数据库后端不能有一个较为 portable 的实现。但是很快就发现,该目标机上没有一个运行的 mysqld 进程,也就意味着我必须在没有 root 权限的情况下运行一个完整的 MySQL session。好在已经有人做过这件事,因此也找到了对应的命令:

首先初始化 MySQL 的环境,这里假定我们所有的文件都保存在 $HOME/mysql 下,使用如下命令运行 mysqld 进行初始化:

MYSQL_HOME=/homes/<user>/mysql
BASE_DIR=$MYSQL_HOME
DATADIR=$BASE_DIR/data
mysqld --user=asset-wiki-admin --datadir=$DATADIR --basedir=$MYSQL_HOME --log-error=$MYSQL_HOME/log/mysql.err --pid-file=$MYSQL_HOME/mysql.pid --socket=$MYSQL_HOME/socket --port=32303 --initialize

之后会生成一个默认的 root 密码在 mysql/log/mysql.err 最后一行,去把它记下来,之后会用到。

然后普通运行 mysqld 可以使用如下命令:

MYSQL_HOME=/homes/<user>/mysql
BASE=$MYSQL_HOME
/usr/sbin/mysqld --datadir=$BASE/data --basedir=$BASE --log-error=$BASE/log/mysql.err --pid-file=$BASE/mysql.pid --socket=$BASE/socket --port=32303 &

停止 mysqld 使用如下命令:

MYSQL_HOME=/homes/<user>/mysql
BASE=$MYSQL_HOME
/usr/bin/mysqladmin --socket=$BASE/socket shutdown -u root -p

如果要不使用交互式密码登录,那么将 -p 命令替换成 -ppassword,这里假定密码就是 password,注意这里不要空格。

如果要启动一个 MySQL 实例,那么这么做:

MYSQL_HOME=/homes/<user>/mysql
BASE=$MYSQL_HOME
/usr/bin/mysql --socket=$BASE/socket --port=32303 -u root -p

注意 32303 是我随便选的本地监听端口,可以换成任意一个可用端口。

在完成本地数据库环境搭建以后,在源服务器上 dump 数据库,在目标服务器上创建数据库和用户并授予权限,之后按照文档中的命令将其导入。

下一步就是在 web server 的目录中放入 MidiaWiki 的文件,然后访问网址进行自动安装,在填写了数据库密码之后,会自动进行数据库的适配过程。之后就会生成当前的 LocalSettings.php 文件。

为了保持原始的设定,我们可以将源服务器上的 LocalSettings.php 拷贝过来,并且将里面的内容根据新的环境做一些修改。需要修改的变量在这里可以看到。主要是修改一些路径相关的文件夹和数据库的连接方式。到这里理论上就可以结束了,但是还要记录一些问题。

关于 PDF 缩略图的生成,MediaWiki 默认通过 PdfHandler 这个插件基于 ImageMagick 和 GhostScript 完成转换和生成工作。这个需要注意的是 $wgMaxShellMemory 这个配置项,可以调整为 ‘unlimited’,以免生成时出现类似

Error creating thumbnail: convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/504. convert: no images defined `/tmp/transform_efffbb473a62.jpg' @ error/convert.c/ConvertImageCommand/3258

这样的错误。

另外一个需要注意的问题是,ImageMagick 可能禁止转换 PDF 文件,具体要查看 /etc/ImageMagick/policy.xml 或者通过 convert -list policy 查看,确认 PDF 格式的权限是 Read|Write 而非 none。如果系统配置为 none,如没有 root 权限,只能编译安装 ImageMagick,注意一定要做一个 module build。

之后在 ~/.config/ImageMagick/policy.xml 中写入对应的配置就可以了。

另外一个错误是:

Notice: Undefined offset: 0 in /home/asset-wiki/htdocs/includes/libs/mime/MimeAnalyzer.php on line 809

这个是 MediaWiki 1.33 和 PHP 兼容性导致的。具体参考这里的改动。主要就是将 809 行最后的 [0] 改成 [1] 就能解决问题。

如果上传一个 pptx 文件的时候 wiki 报错认为 MIME 类型是 application/zip,这个是 PHP fileinfo 模块的锅,可以用 $wgVerifyMimeType = false; 强行关闭 MIME 类型检查。具体看这里

在 Linux 下使用 Office 365

在 Windows 上用习惯了微软全家桶,切到 Linux 就没指望了,又不能说装个 Windows 虚拟机就为了用 Office 365,那只好尝试找找替代品了。

首先是 Outlook,包含了学校账户的 Exchange ActiveSync,个人 Outlook 邮箱还有日程功能。在 Linux 上比较常见的邮件客户端是 Mozilla Thunderbird,通过插件配置可以最低限度地支持 Outlook 提供的一些服务。

  • owl for exchange 提供 Exchange ActiveSync 的邮件支持
  • lightning 提供 Outlook 日历的基础功能支持
  • tbsync + provider for exchange activesync 提供到 Office 365 账户的日历同步功能
  • provider for google calendar 为 lightning 提供到 Google Calendar 的同步功能

有了这些插件以后,就可以依次添加自己的账户开始同步了。不能说多好用,勉强能用吧。

然后是 Microsoft To-Do,这个有好事者开发了一个跨平台的版本:klaussinani/ao。通过 snap 就可以安装。

还有 OneNote,这个似乎除了网页版就没有什么比较好用的版本,不过也有好事者用 Electron 做了一个本地网页客户端:patrikx3/onenote。还算能用,也是通过 snap 安装。

OneDrive 的同步,也有好事者写了 Linux 上可用的版本:skilion/onedrive。这个要写一下正确的安装流程,我装的时候差点就把 OneDrive 里面的文件全部删掉了,幸好有回收站。

对于 Ubuntu 18.04,安装流程是这样的:

sudo apt install libcurl4-openssl-dev
sudo apt install libsqlite3-dev

# Ubuntu 18
sudo snap install --classic dmd && sudo snap install --classic dub

git clone https://github.com/skilion/onedrive.git
cd onedrive
make
sudo make install

注意,在运行之前,一定是在运行之前,自行在 ~/.config 下创建配置文件目录,以 ~/.config/onedrive 为例,如果需要同步多个账户则应使用不同的目录名称:

mkdir -p ~/.config/onedrive
cp ./config ~/.config/onedrive/config
nano ~/.config/onedrive/config

config 文件结构类似这样:

# Directory where the files will be synced
sync_dir = "~/OneDrive"
# Skip files and directories that match this pattern
skip_file = ".*|~*"

标记了默认的同步路径为 ~/OneDrive,由于在首次运行 onedrive 的时候默认就是授权,因此如果要更改同步目录的话,在这里要先在配置文件里面写好。然后运行 onedrive –confdir=”~/.config/onedrive” 开始进行授权操作,这样就会在 sync_dir 处创建对应的文件夹,然后开始下载。

如果要自动同步,在 make install 之后,在 /usr/lib/systemd/user 下已经被创建了一个 onedrive.service 文件,类似这样:

[Unit]
Description=OneDrive Free Client
Documentation=https://github.com/skilion/onedrive

[Service]
ExecStart=/usr/local/bin/onedrive -m
Restart=no

[Install]
WantedBy=default.target

如果想要同步多个账户的话,把 ExecStart 改成类似于 onedrive -m –confdir=”~/.config/onedrivePersonal” 这样带有配置文件目录的形式。之后:

systemctl --user enable onedrive
systemctl --user start onedrive

就可以启动服务自动运行了。

如果不想使用 User Service,希望在系统启动时运行,则在 /etc/systemd/system 下创建 onedrive.service,写入类似于:

[Unit]
Description=OneDrive Free Client
Documentation=https://github.com/skilion/onedrive

[Service]
ExecStart=/usr/bin/sudo -u <user> /usr/local/bin/onedrive -m --confdir="/home/<user>/.config/onedrive"
Restart=always

[Install]
WantedBy=default.target

之后:

systemctl enable onedrive
systemctl start onedrive

切记,不能在授权完成之后,复制 config 文件并更改 sync_dir,然后直接用 -m 参数运行 onedrive,这样会使得该程序认为本地有全部删除的更改,会直接删掉 OneDrive 上所有文件。所以一定要先写配置文件再授权。

最后记录一下添加 SMB 打印机的过程,Linux 通过 CUPS 管理打印机,但是图形界面的管理未必好用,可以尝试用 localhost:631 来管理,注意 cups-2.2.7 在 Linux 版 Chrome 上有 bug,会出现 unauthorized error,这个需要升级到 2.2.8 或者使用 firefox。具体配置可以看 Arch Wiki

在物理机上全新安装 Ubuntu 的一些坑

起因是这样的,老板表示都搞 Research 了,日常使用就用 Ubuntu 吧……然后就在一台 Dell Optiplex 5060 上装起了 Ubuntu。

这台机器本身没有 SSD,IT 搬过来的时候系统就装在一块 500G/7200rpm 的海门酷鱼上(ST500LM034)。9102 年了,我用 SSD 装系统都用了 7 年了,没有 SSD 的机器完全没法用,遂购入一块 NVMe SSD 插在了 M.2 接口上,然后插入 xubuntu 安装 U 盘开始重装。

这时候问题来了,尽管在 BIOS 里能看到,但是 Ubuntu 死活检测不到那块 NVMe。经多处查询,发现可以尝试在 BIOS 中把默认的 SATA 模式改成 AHCI,而不是 RAID,改过来以后,就没问题了。此处要吐槽一下 Dell 知识库,里面写的完全是反的,表示应该把 AHCI 模式改成 RAID,我信你就有鬼了。

安装流程很快完成以后,又出现了另外一个问题,xubuntu 18.04.3 已经默认使用了 HWE Kernel,在尝试安装 openssh-server 的时候,表示有部分依赖无法满足。之前遇到这个问题的时候,尝试过 aptitude,给出的方案之一是降级大量的软件包,但是这样之后把系统的包搞得一团糟,apt 已经完全无法正常使用。考虑到默认使用的是 HWE kernel,在 aptitude 降级的时候也出现过卸载带 hwe 后缀的软件包,安装不带 hwe 后缀的软件包的操作,因此怀疑是软件源的问题。

于是在这里生成新的软件源列表,注意勾选 main restricted universe multiverse、security updates 和 backports 这些,生成链接之后,复制到 /etc/apt/sources.list 中。在 apt udpate 之后,发现整个系统终于能正常工作了。现在看来,ubuntu 18.04 使用 HWE Kernel 的版本在默认的软件源列表上是有坑的,似乎是 bionic-updates 没有被包含在其中,造成软件包版本混乱的问题。

在解决了这些问题之后,似乎至少能正常使用了。

iKoula 独服在 netplan.io 下配置 IPv6

netplan.io 实在是太烂了

假设 IPv4 地址是 AAA.BBB.CCC.DDD,修改 /etc/netplan/01-netcfg.yaml

# Network configuration file
# Auto generated by Ikoula

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses: 
        - AAA.BBB.CCC.DDD/24
        - "2a00:c70:1:AAA:BBB:CCC:DDD:1/96"
      gateway4: AAA.BBB.CCC.1
      gateway6: 2a00:c70:1:AAA:BBB:CCC::1
      nameservers:
        addresses: [213.246.36.14,213.246.33.144,80.93.83.11]

之后 netplan try 验证格式并回车应用,或者直接 netplan apply

WordPress 迁移

从……大概一年多以前?Offline 要涨价开始,我就说要抛弃他家 Scaleway,转到 Hetzner Cloud 上来,然而因为懒……所以就一直没弄。今天突发奇想就弄了一下。

WordPress 迁移的方法有很多,可以考虑底层的方法把网站目录、数据库和 nginx 配置文件连锅端,也可以用一些插件辅助完成这个事情。出于懒……我个人选择了插件。

在这个迁移中使用的是 All-in-One WP Migration 插件,其作者声称可以直接打包把站点导出,包含所有的文章、主题以及插件信息。为了测试该插件能否正常工作,我首先使用了另一个二级域名并安装 WordPress 作为测试平台,很顺利地完成了导入以后,就开始了主域名的迁移工作。

由于我的环境是 Oneinstack 的 LNMP 一件包,其 vhost 管理并没有提供相应的更改域名功能,在阅读了代码之后,发现其功能似乎是 stateless 的,也就是说包括 vhost 列表的查询以及 Let’s encrypt 证书管理在内都通过读取对应应用程序的配置文件完成,而非本地再对已有的域名进行配置文件的保存。这样的设计为我之后要干的事情提供了极大的方便,即手动更改本地域名地址之后,只要不变动文件夹结构,就不会影响该脚本的后续使用。

迁移这个简单的 WordPress 站点(没什么特殊配置,都在 WP 框架内完成,因此使用迁移插件即可),需要做的有这样几件事:

  • 导出原站点
  • 在新 VPS 上建立 vhost,并申请 Let’s encrypt 证书
  • 安装 WordPress
  • 导入原站点

需要注意的一点是,如果需要在 vhost 中更改域名,一定要在安装 WordPress 之前完成,因为 WordPress 似乎根据安装时保存在 MySQL 数据库中的网址自行进行 301 跳转,即使更改了 nginx 中的网址,Wordpress 仍然会在后续访问中跳转会原来的地址,进而会导致 https 证书地址不匹配的问题。

这个问题最开始是在完成了使用测试域名的导入以后,想更换为原来的主域名时发生的。在使用 acme.sh 生成证书并安装,且完成 nginx config 中的证书路径修改之后:

acme.sh --issue -d <domain> --webroot <web_root_dir>
acme-sh --install-cert -d <domain> --key-file /usr/local/nginx/conf/ssl/<domain>.key --fullchain-file /usr/local/nginx/conf/ssl/<domain>.crt --reloadcmd  "service nginx force-reload"

在访问原网址时仍然会跳转到之前使用的测试网址,这让我百思不得其解。在删除网站根目录下的所有文件,重新生成证书以及 vhost 配置文件等方法均无果之后,我使用了使用 curl -I 查看调试信息:

# curl -I https://blog.gloriousdays.pw
HTTP/2 301
server: nginx
date: Sun, 25 Aug 2019 16:36:56 GMT
content-type: text/html; charset=UTF-8
location: https://blog2.gloriousdays.pw/
x-redirect-by: WordPress
strict-transport-security: max-age=15768000

可以看到似乎是由 WordPress 完成的 301 跳转。与之相对的正常访问和 nginx 完成的 301 跳转是这样:

# curl -I https://blog.gloriousdays.pw
HTTP/2 200
server: nginx
date: Sun, 25 Aug 2019 17:46:59 GMT
content-type: text/html; charset=UTF-8
content-length: 41183
vary: Accept-Encoding
vary: Accept-Encoding, Cookie
cache-control: max-age=3, must-revalidate
last-modified: Sun, 25 Aug 2019 17:34:44 GMT
strict-transport-security: max-age=15768000

# curl -I http://blog.gloriousdays.pw
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 25 Aug 2019 17:47:03 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://blog.gloriousdays.pw/
Strict-Transport-Security: max-age=15768000

这样似乎就定位了问题所在,Wordpress 在某个地方存储了网站的地址,并且依照其进行跳转。后来想到,在进行网站测试导入时,已经完成了 WordPress 安装并连接了数据库,在之前删除网站目录文件重新放入 WordPress 安装包的时候也没有进行清除,或许那个数据库才是问题所在。于是果断进入 mysql 命令行 drop database,并重新进行安装和导入站点流程,这时候网站就已经正常工作了。

总结一下的话,就是在安装 WordPress 之后一定不要更改 nginx 对应的域名,说实话这也很奇怪,301 跳转这个功能委托给 nginx 完成就好,WP 何必多此一举呢。

修改 Linux 默认 locale 使得非 ASCII 字符在 ssh 下可以正常显示

一般来说,如果没有进行过特殊配置的话(比如说我们用 debootstrap 安装的系统),其默认 locale 会是 POSIX,我们使用 locale 命令可以看到这个情况。

# locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

C 是系统默认的 locale,而 POSIX 是 C 的别名,因此这里看到的情况就是默认的 C Locale。它所指定的属性和行为由 ISO C 标准所指定。当我们新安装完一个系统时,默认的 locale 就是 C 或 POSIX。我们这里说的 C 其实就是 ASCII 编码。

但是我们同样也知道,标准的 ASCII 字符集中是不包含中文、日文等字符的,因此如果 POSIX 作为系统默认的 locale,那么会遇到在 SSH 下无法正确显示这些字符的问题,会直接按字节解析为 ASCII 转义字符,因此要想更正这个情况只有修改系统默认的 locale。

通过 locale -a 可以查看当前系统可用的所有 locale:

# locale -a
C
C.UTF-8
POSIX
en_US.utf8

显然,en_US.utf8 是一个好选择。

下面贴过来一段对上文中提及的 LC_* 环境变量的接释:

  • LANG
    LANG的优先级是最低的,它是所有 LC_* 变量的默认值。下方所有以 LC_ 开头变量(不包括LC_ALL)中,如果存在没有设置变量值的变量,那么系统将会使用 LANG 的变量值来给这个变量进行赋值。如果变量有值,则保持不变,不受影响。可以看到,我们上面示例中的输出中的 LC_*变量的值其实就是 LANG 变量决定的
  • LC_CTYPE
    用于字符分类和字符串处理,控制所有字符的处理方式,包括字符编码,字符是单字节还是多字节,如何打印等,这个变量是最重要的。
  • LC_NUMERIC
    用于格式化非货币的数字显示。
  • LC_TIME
    用于格式化时间和日期。
  • LC_COLLATE
    用于比较和排序。
  • LC_MONETORY
    用于格式化货币单位。
  • LC_MESSAGES
    用于控制程序输出时所使用的语言,主要是提示信息,错误信息,状态信息, 标题,标签, 按钮和菜单等。
  • LC_PAPER
    默认纸张尺寸大小
  • LC_NAME
    姓名书写方式
  • LC_ADDRESS
    地址书写方式
  • LC_TELEPHONE
    电话号码书写方式
  • LC_MEASUREMENT
    度量衡表达方式
  • LC_IDENTIFICATION
    locale对自身包含信息的概述
  • LC_ALL
    它不是环境变量,它是一个宏,可通过该变量的设置覆盖所有的 LC_* 变量。这个变量设置之后,可以废除 LC_* 的设置值,使得这些变量的设置值与 LC_ALL 的值一致,注意,LANG 变量不受影响。在这里,这个宏操作就是用 LC_ALL 的值去覆盖 LC_* 的变量值

从描述中可以看出,优先级级别:LC_ALL > LC_* > LANG

注意:定义这么多变量在某些情况下是很有用的,例如,当我需要一个能够输入中文的英文环境,我可以把 LC_CTYPE 设定成 zh_CN.GB18030,而其他所有的项都是 en_US.UTF-8。

如果我们要修改这个默认的变量,可以在自己的 ~/.bashrc 中进行 export,比如我加入了这两行:

export LANG=en_US.utf8
export LC_CTYPE=en_US.utf8

之后重新登录一下就可以正常显示 Unicode 字符了。