shellscript (zsh) 中的 echo 复选标记操作方法

shellscript (zsh) 中的 echo 复选标记操作方法

为什么在执行我的 shellscript 时这个复选标记没有正确打印,即使 echo 单独输出正确?

脚本:

#!/bin/sh
YELLOW='\033[1;33m'
NC='\033[0m' # no color
echo "enter your provider's auth code"
stty -echo
read authcode
oathtool --totp -b $authcode | xclip -i
echo "${YELLOW}\u2714 code copied to clipboard${NC}"

终端输出:\u2714 代码已复制到剪贴板

独立命令:

echo "\u2714 checkmark"

终端输出: ✔ 复选标记

我的外壳是zsh 5.8 (x86_64-debian-linux-gnu) 使用rxvt-unicode-256color终端

答案1

你的 shebang 有/bin/sh,我怀疑你的系统上/bin/sh有。不是 Debian 批准的实现之一。无论如何,我建议不要在脚本中使用非标准语法。zshzshshshsh

\u2714不是标准echo语法。它(可能)将成为$'...'POSIX 标准的下一个主要修订版中的标准,但不会出现在echoor的参数中printf,并且无论如何 Debian 的默认sh实现 ( dash) 还不支持$'...'

\uXXXXzsh被's printf(在格式参数或 的参数中%b)、print(aw 除外-r)和echo(除非启用-Ebsdecho启用该选项)内建函数和其内部(这是在其中引入$'...'这些序列的第一个 shell)、引号本身所识别来自 ksh93)。\uXXXX$'...'$'...'

#! /bin/zsh -如果您想zsh在脚本中使用功能,请将 shebang 更改为。

然后,您可以使用更多 zsh 功能,例如:

print -P '%B%F{yellow}\u2714 whatever%f%b'

使用%F{yellow}romptP扩展将扩展为终端的正确代码,以将F矿石颜色更改为黄色的%f并将前景色重置为默认值,和%B/%b启用/禁用大胆的就像你的\033[1m)。

在 中zsh,您还可以执行以下操作:

IFS= read -rs 'authcode?enter auth code: '

更可靠地发出提示并实现s静默输入。

在任何情况下,就像在 中一样sh,您可能希望-rIFS=避免read损坏输入。

您还可以使用set -o pipefail该管道,如果或失败(不仅仅是),oathtool | xclip则被视为失败。oathtoolxclipxclip

请注意,如果区域设置的字符编码没有 U+2714 字符,print则会失败并出现zsh: character not in range错误。


在标准sh+实用程序语法中,语法应该是:

#! /bin/sh -
bold_yellow='\033[1;33m'
nc='\033[m' # no color
if [ "$(locale charmap)" = UTF-8 ]; then
  check_mark='\0342\0234\0224'
else
  check_mark='[X]'
fi

saved_tty_settings=$(stty -g)
trap 'stty "$saved_tty_settings"' EXIT ALRM TERM INT QUIT
stty -echo
printf >&2 "enter your provider's auth code: "
IFS= read -r authcode &&
  secret=$(oathtool --totp -b "$authcode") &&
  printf %s "$secret" | xclip -i &&
  printf '%b\n' "${bold_yellow}${check_mark} code copied to clipboard${nc}"

这里对着色转义序列进行硬编码,并且仅当区域设置的字符映射是 UTF-8 时才对 U+2714 的 UTF-8 编码进行硬编码。

或者你可以这样做:

check_mark=$(printf '\342\234\224' | iconv -f UTF-8 2> /dev/null) ||
  check_mark='[X]'

获取check_mark区域设置的字符映射(如果有的话)(并且UTF-8系统支持),[X]否则获取。 GB18030 是我所知道的唯一具有 U+2714 的其他字符映射。它也是 Unicode 的一种编码,主要在中国使用(如zh_CN.gb18030Debian 上的语言环境)。

相关内容