Если вам нужно поддерживать только одну раскладку клавиатуры в виртуальной машине, то проще всего будет жестко закодировать преобразование в вашем скрипте.
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
Однако разбор этих файлов для построения таблиц преобразования будет нетривиальной работой, и я не знаю, было ли это сделано.
Как сообщил 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
Обратите внимание, что \ 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.
Использование необработанного юникода:
$ echo -e '☑ done\n☒ fail\n☐ to do'
☑ done
☒ fail
☐ to do