在 shell 脚本中打印复选/十字标记

use*_*695 10 shell-script echo unicode

我想在 shell 脚本中打印一个复选标记和一个十字标记:

#!/bin/bash

echo -e "\xE2\x9C\x94 existing"
echo -e "\xE2\x9D\x8C missing"
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?

Ser*_*nyy 14

正如 OP 在评论中透露的那样,他们使用sh file.sh. 根据/bin/sh符号链接到的默认 shell,它可能不支持 unicode 字符。

例如,在 Ubuntu 上,默认的 shell 是dash.

$ dash
$ printf "\xE2\x9C\x94 missing\n"
\xE2\x9C\x94 missing
$ echo -e "\xE2\x9C\x94"
-e \xE2\x9C\x94
Run Code Online (Sandbox Code Playgroud)

当您在交互式 shell 中调用命令时它起作用的原因是因为默认情况下用户交互式 shell(在 Ubuntu 上) /bin/bash

要正确运行脚本,您需要:

  • 运行它 ./file.sh
  • 将它作为参数运行到正确的 shell bash file.sh

或者,可以采用与 shell 无关的方法:

# this printf is standalone program, not shell built-in
$ /usr/bin/printf "\xE2\x9C\x94 check mark\n"
? check mark

$ python -c 'print "\xE2\x9C\x94 check mark"'
? check mark

$ perl -e 'print "\xE2\x9C\x94 check mark"'                                                                              
? check mark
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 10

请注意,这\xE2\x9C\x94是 U+2714(重复选标记)字符的 UTF-8 编码。

如果终端的字符集是 UTF-8(并使用具有该字符的字体),则这 3 个字节将仅显示为复选标记。

对于终端模拟器,它们使用的字符集通常是它们启动时区域设置中的字符集。除非您更改了在该终端中启动的 shell 中的区域设置,否则您可以分辨出它是哪个区域设置:

locale charmap
Run Code Online (Sandbox Code Playgroud)

几个printf实施方式中包括GNUprintfprintf的内置zshbashlksh(更POSIX兼容变体mksh支撑件上至少基于Debian的系统):

$ printf '\u2714\u274c\n'
??
Run Code Online (Sandbox Code Playgroud)

以正确的语言环境字符集编码打印这些字符(ksh93 的printf内置程序也支持该\uXXXX表示法,但无论语言环境的字符集如何,始终以 UTF-8 输出)。printf内置支持它并具有echo扩展转义序列(可能带有-e)的外壳通常也支持\uXXXX它。

现在,AFAICT,这两个 U+274C 和 U+2714 字符在典型的 GNU 系统上可用的唯一两个字符集是 UTF-8 和 GB18030。在使用不同字符集的语言环境中,printf将无法显示这些字符,因为它们根本不存在。根据实现,printf将按\u274C字面打印或因错误而失败。

一些 shell(zsh它起源于 , bash, ksh93, mkshFreeBSD sh)也在\uXXXX它们的$'...'引号中支持这种表示法。

所以你可以这样做:

echo $'\u2714\u274c'
Run Code Online (Sandbox Code Playgroud)

根据外壳程序,这些将扩展为在解析命令 ( bash) 或运行命令 ( zsh) 或始终采用 UTF-8 (ksh)时生效的区域设置编码。

POSIXly(在类 Unix 系统中可移植),如果要打印任意字节序列,则需要使用printf和 八进制表示法。

\xE2\x9C\x94 (U+2714 的 UTF-8 编码)将打印在一行上:

printf '\342\234\224\n'
Run Code Online (Sandbox Code Playgroud)

如果您希望将其转换为语言环境的正确编码,那就是:

printf '\342\234\224\n' | iconv -f UTF-8
Run Code Online (Sandbox Code Playgroud)

POSIX 没有指定系统可能支持哪种字符编码,也没有指定它们的名称,但上述命令通常适用于支持 UTF-8 编码的 POSIX 系统。