Печатать галочку / крестик в сценарии оболочки

Если вам нужно поддерживать только одну раскладку клавиатуры в виртуальной машине, то проще всего будет жестко закодировать преобразование в вашем скрипте.

typeset -A scancodes
scancodes['1']='02 82'  # press 1, release 1
scancodes['!']='2a 02 82 aa'  # press left Shift, press 1, release 1, release left shift
…
# emit_scancodes VM STRING
emit_scancodes () {
  typeset a=; typeset c string="$2"
  while [ -n "$string" ]; do
    c=${scancodes[${string:0:1}]
    if [ -z "$c" ]; then
      echo >&2 "Unsupported character: ${string:0:1}"
      return 1
    fi
    a+=("$c")
    string=${string:1}
  done
  for c in "${a[@]}"; do
    virtualbox controlvm "$1" keyboardputscancode
    # For long strings, you may need an additional short sleep here
  done
}

Если вам нужно поддерживать различные раскладки клавиатуры, то вы можете использовать карты клавиш консоли Linux из данных Linux Console Tools. Эти файлы содержат строки типа

keycode 16 = q
keycode   2 = one              exclam

Однако разбор этих файлов для построения таблиц преобразования будет нетривиальной работой, и я не знаю, было ли это сделано.

5
04.11.2019, 13:13
3 ответа

Как сообщил OP в комментариях, они вызывали скрипт с sh file.sh . В зависимости от оболочки по умолчанию, к которой привязана символическая ссылка / bin / sh , она может не поддерживать символы Unicode.

Например, в Ubuntu оболочка по умолчанию - тире .

$ dash
$ printf "\xE2\x9C\x94 missing\n"
\xE2\x9C\x94 missing
$ echo -e "\xE2\x9C\x94"
-e \xE2\x9C\x94

Причина, по которой это сработало, когда вы вызывали команду в интерактивной оболочке, заключается в том, что интерактивная оболочка пользователя по умолчанию (в Ubuntu) / bin / bash

Для правильного запуска сценария вам необходимо:

  • запустите его как ./ file.sh
  • запустите его как аргумент соответствующей оболочки bash file.sh

В качестве альтернативы можно использовать методы, не зависящие от оболочки:

# 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
14
27.01.2020, 20:33

Обратите внимание, что \ xE2 \ x9C \ x94 - это кодировка UTF-8 символа U + 2714 ( жирная галочка ).

Эти 3 байта будут отображаться как галочка, только если набор символов терминала - UTF-8 (и используется шрифт, содержащий этот символ).

Для эмуляторов терминала кодировка, которую они используют, обычно совпадает с кодировкой, установленной на момент их запуска. Если вы не изменили языковой стандарт в оболочке, запущенной в этом терминале, вы можете сказать, с какой он был:

locale charmap

Несколько реализаций printf , включая GNU printf и printf встроенный zsh , bash и lksh (более POSIX-совместимый вариант mksh , по крайней мере, в системах на базе Debian) поддержка:

$ printf '\u2714\u274c\n'
✔❌

Чтобы напечатать эти символы в правильной кодировке для кодировки языкового стандарта (встроенная функция ksh93 printf также поддерживает эту нотацию \ uXXXX , но всегда выводит в UTF-8 независимо от языкового стандарта кодировка). Оболочки, в которых встроена printf , поддерживают его и имеют echo , расширяющее escape-последовательности (возможно, с помощью -e ), обычно также поддерживают \ uXXXX там .

Теперь, AFAICT, единственные две кодировки, где эти два символа U + 274C и U + 2714 доступны в типичной системе GNU, - это UTF-8 и GB18030. В локали, использующей другие кодировки, printf не сможет отображать эти символы, поскольку они просто не существуют. В зависимости от реализации printf напечатает \ u274C буквально или завершится ошибкой.

Некоторые оболочки ( zsh , где они возникли, bash , ksh93 , mksh , FreeBSD sh ) также поддерживают нотацию \ uXXXX в своих кавычках $ '...' .

Итак, вы можете:

echo $'\u2714\u274c'

В зависимости от оболочки они будут расширены до кодировки языкового стандарта, которая действовала во время анализа команды ( bash ) или в то время, когда она была запустите ( zsh ) или всегда используйте UTF-8 (ksh).

В POSIX (переносимо среди Unix-подобных систем), если вы хотите напечатать произвольную последовательность байтов, вы захотите использовать printf и восьмеричную нотацию.

\ xE2 \ x9C \ x94 (кодировка UTF-8 для U + 2714) будет напечатана в переносимой строке с:

printf '\342\234\224\n'

И если вы хотите, чтобы она была преобразована в правильную кодировку для локали , это будет:

printf '\342\234\224\n' | iconv -f UTF-8

POSIX не указывает, какая кодировка символов может поддерживаться в системе, или их имя, но приведенная выше команда обычно работает в системах POSIX, которые поддерживают кодировку UTF-8.

10
27.01.2020, 20:33

Использование необработанного юникода:

$ echo -e '☑ done\n☒ fail\n☐ to do'
☑ done
☒ fail
☐ to do
3
27.01.2020, 20:33

Теги

Похожие вопросы