Imprimir cheque / marca cruzada no shell script

2

Gostaria de imprimir uma marca de seleção e uma marca cruzada em um script de shell:

#!/bin/bash

echo -e "\xE2\x9C\x94 existing"
echo -e "\xE2\x9D\x8C missing"

Por que isso não está funcionando?

    
por user3142695 10.02.2017 / 09:30

3 respostas

5

Conforme revelado pelo OP nos comentários, eles estavam chamando o script com sh file.sh . Dependendo do shell padrão para o qual /bin/sh é symlinked, ele pode não suportar caracteres unicode.

Por exemplo, no Ubuntu, o shell padrão é dash .

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

O motivo pelo qual funcionou quando você chamou o comando no shell interativo, é porque o shell interativo dos usuários é por padrão (no Ubuntu) /bin/bash

Para executar corretamente o script, você precisa:

  • executá-lo como ./file.sh
  • executá-lo como argumento para o shell adequado bash file.sh

Como alternativa, pode-se recorrer a métodos independentes de 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
    
por 10.02.2017 / 10:02
2

Observe que \xE2\x9C\x94 é a codificação UTF-8 do caractere U + 2714 ( marca de verificação pesada ).

Esses 3 bytes serão exibidos apenas como uma marca de verificação se o conjunto de caracteres do terminal for UTF-8 (e usar uma fonte que tenha esse caractere).

Para emuladores de terminal, o conjunto de caracteres que eles usam normalmente será aquele no local no momento em que foram iniciados. A menos que você tenha alterado a localidade dentro do shell iniciado naquele terminal, você pode dizer com qual delas estava:

locale charmap

Diversas implementações printf incluindo GNU printf e printf embutido de zsh , bash e lksh (pelo menos um variante compatível com POSIX de mksh no sistema baseado em Debian) :

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

Para imprimir esses caracteres na codificação correta para o conjunto de caracteres do código de idioma (o printf builtin de ksh93 também suporta essa notação de \uXXXX , mas sempre gera saída em UTF-8, independentemente do conjunto de caracteres do código do idioma). Shells cujo printf builtin o suporta e tem um echo que expande as seqüências de escape (possivelmente com -e ) normalmente também suportam \uXXXX .

Agora, AFAICT, os únicos dois conjuntos de caracteres onde os dois caracteres U + 274C e U + 2714 estão disponíveis em um sistema GNU típico são UTF-8 e GB18030. Em locais usando conjuntos de caracteres diferentes, printf não poderá exibir esses caracteres, pois eles simplesmente não existem. Dependendo da implementação, printf imprimirá \u274C literalmente ou falhará com um erro.

Alguns shells ( zsh de onde é originado, bash , ksh93 , mksh , FreeBSD sh ) também suportam essa \uXXXX de notação em suas cotas $'...' .

Então você pode fazer:

echo $'\u2714\u274c'

Dependendo do shell, eles serão expandidos para a codificação do locale que estava em vigor no momento em que o comando foi analisado ( bash ) ou no momento em que foi executado ( zsh ) ou em UTF-8 sempre (ksh).

POSIXly (portável entre sistemas similares ao Unix), se você quiser imprimir seqüências arbitrárias de bytes, você vai querer usar printf e a notação octal.

\xE2\x9C\x94 (a codificação UTF-8 de U + 2714) seria impresso em uma linha portável com:

printf '244\n'

E se você quiser que ele seja convertido para a codificação correta da localidade, isso seria:

printf '244\n' | iconv -f UTF-8

O POSIX não especifica qual codificação de caracteres pode ser suportada em um sistema, nem seu nome, mas o comando acima normalmente funcionaria em sistemas POSIX que suportam a codificação UTF-8.

    
por 10.02.2017 / 12:16
0

Uso do unicode bruto:

$ echo -e '☑ done\n☒ fail\n☐ to do'
☑ done
☒ fail
☐ to do
    
por 10.02.2017 / 10:27