Quando executado via SSH, o R parece tratar caracteres não ASCII de forma diferente, dependendo do sistema operacional do cliente SSH.
Por exemplo, se eu usar um computador executando macOS (14.6.1) para iniciar uma sessão R em uma máquina Ubuntu (22.04.5) e executar:
units::set_units(12.7, "\U00B5m")
Eu entendo:
12.7 [µm]
Mas a mesma expressão executada no mesmo servidor, mas por um cliente Windows (10.0.19045.4170) produz:
Error: In '<U+00B5>m', '<U+00B5>m' is not recognized by udunits.
Pensei que isso poderia ter a ver com a forma como a linha de comando em cada SO envia as representações de caracteres por SSH. No entanto, se eu salvar o seguinte script no servidor (escrito usando vim por SSH da máquina macOS):
#!/bin/Rscript
print(nchar("µm"))
E executá-lo via SSH a partir do cliente macOS (por exemplo, ssh <user>@<host> "./print_micron.R"
), obtenho:
[1] 2
ou seja, "µ"
é um único caractere de dois bytes. Mas se eu executar isso do cliente Windows, eu obtenho:
[1] 3
ou seja, "µ"
torna-se dois caracteres separados, um para cada byte.
Isso está desafiando minha intuição de como a execução de comandos em SSH funciona, pois eu esperaria que o comportamento do R fosse determinado inteiramente pelo servidor. Por que o SO cliente afetaria como caracteres não-ASCII são representados pelo R?
Seu Mac provavelmente tem
LANG=en_US.UTF-8
(ou algo similar) no ambiente, que define o local padrão para usar a codificação UTF-8. Ele provavelmente também tem SSH configurado para encaminhar essa variável de ambiente para o servidor (SendEnv LANG
na configuração SSH). Isso faz com que o R use UTF-8 para sua codificação interna e para ler arquivos de origem.Seu cliente SSH do Windows, por outro lado, provavelmente não está enviando nenhuma variável desse tipo, e nada no servidor está padronizando-a, então você obtém o
C
locale, que é somente ASCII. Isso faz comunits
que você não saiba o que o caractere B5 significa (não há caracteres acima de 7F em ASCII!), e faz com que o literal de string no seu script de teste seja interpretado como três caracteres (um por byte) em vez de dois.Você deve conseguir ver a diferença executando
sessionInfo()
el10n_info()
em dois clientes diferentes: eles mostrarão valores diferentes paralocale
,codeset
eUTF-8
.Se o seu cliente SSH do Windows puder manipular UTF-8, você poderá:
LANG
à lista de variáveis de ambiente que ele envia ao servidor, se tiver uma configuração para isso.export LANG=en_US.UTF-8
(ou qualquer valor que seja apropriado para você) ao seu~/.profile
ou~/.bashrc
no servidor (ou o que você tiver que seja obtido automaticamente quando você efetuar login).