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
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
实施方式中包括GNUprintf
和printf
的内置zsh
,bash
和lksh
(更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
, mksh
FreeBSD 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 系统。