Вопрос или проблема
Когда я подключаюсь к серверу Arch Linux по SSH и включаю командную строку, я получаю POSIX locale:
laptop.lan$ ssh server.lan locale
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
laptop.lan$
Насколько я могу судить, locale настроен правильно на сервере. /etc/locale.conf
выглядит так:
LANG=en_US.UTF-8
И когда я подключаюсь по SSH в обычном режиме, мой locale в порядке:
laptop.lan$ ssh server.lan
server.lan$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
server.lan$
Что здесь происходит, и как я могу заставить одноразовые команды использовать мой предпочтительный locale?
Я думаю, здесь применяются некоторые значения по умолчанию, я не уверен в версии, но мои первые мысли такие:
Переслать locale
SendEnv LANG LC_*
Или
вы можете изменить конфигурацию сервера, отредактировав /etc/ssh/sshd_config на удаленной машине:
Принимать locale
AcceptEnv LANG LC_*
Или
Вы можете использовать файл конфигурации ssh, чтобы передать ваш locale в ~/.ssh/config и использовать
ssh -F ~/.ssh/config your_user@your_host
Или
используйте нижеприведенный способ для внесения изменений на лету
LC_TIME="en_US.UTF-8" ssh usernae@yourserver
Я просто заметил, что проблема возникает, когда у меня установлен fish
(fish-shell) по умолчанию (chsh
). Когда я сменил shell обратно на bash, locale работает как ожидалось.
Итак:
chsh /bin/bash
Ни один ответ не предоставляет ответ на вопрос “почему”, так что позвольте мне опубликовать мой ответ.
Проблема возникает потому, что
-
/etc/locale.conf
загружается из/etc/profile.d/locale.sh
, который выполняется от/etc/profile
, который читается только когда оболочка является login shell. -
Когда вы используете команду
ssh <host>
, запускается login shell. Однако, когда вы используете командуssh <host> <command>
, запускается non-login shell.
Так что попробуйте это обходное решение:
$ ssh <host> 'bash --login -c "locale"'
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Ссылки:
Ответ или решение
Когда вы используете SSH для подключения к серверу Arch Linux и выполняете команду на командной строке, а не инициируете интерактивный сеанс, может возникнуть ситуация, что локаль неправильно установлена в значение POSIX. Это связано с особенностями запуска оболочек в Linux и SSH. Давайте подробно разберем, почему это происходит и как можно исправить подобную ситуацию.
Теория
При подключении с использованием SSH и выполнении команд через него, система может использовать две основные конфигурации оболочки: входная оболочка (login shell) и обычная оболочка (non-login shell). Разница между ними заключается в том, какие конфигурационные файлы загружаются, что влияет на окружение пользователя, включая переменные локали.
-
Входная оболочка (login shell): Когда вы подключаетесь к серверу, используя
ssh <host>
, создается входная оболочка. Она загружает конфигурационные файлы вроде/etc/profile
и тех, что располагаются в домашнем каталоге пользователя, таких как~/.bash_profile
или~/.profile
. Эти файлы часто содержат установки, необходимые для корректного выполнения системы, например, переменные локали. -
Обычная оболочка (non-login shell): Когда вы запускаете
ssh <host> <command>
, создается обычная оболочка, которая не загружает/etc/profile
и другие аналогичные файлы. Это приводит к тому, что переменные, установленные в конфигурационных файлах, могут быть проигнорированы, и система использует значения по умолчанию, такие как POSIX для локали.
Пример
Допустим, у вас на сервере настроено LANG=en_US.UTF-8
в /etc/locale.conf
. Когда вы напрямую подключаетесь к серверу (например, ssh server.lan
), и затем проверяете локаль командой locale
, вы видите, что переменные установлены корректно:
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
...
Однако, при выполнении команды на сервере через SSH команду (например, ssh server.lan locale
), система использует локаль POSIX, потому что не загружаются необходимые конфигурационные файлы:
LANG=
LC_CTYPE="POSIX"
...
Применение
Для решения этой проблемы существует несколько подходов:
-
Явное использование входной оболочки: При выполнении команды через SSH вы можете явно вызвать входную оболочку, чтобы загрузить все необходимые конфигурации:
ssh server.lan 'bash --login -c "locale"'
Этот метод гарантирует, что все скрипты, требуемые для настройки окружения, будут загружены.
-
Конфигурация SSH для передачи локали: Настройте вашу SSH-конфигурацию для передачи переменных локали:
На клиентской машине в
~/.ssh/config
:Host server.lan SendEnv LANG LC_*
На сервере в
/etc/ssh/sshd_config
:AcceptEnv LANG LC_*
После изменений необходимо перезапустить SSH-демон на сервере.
-
Уточнение переменных локали вручную: В случае необходимости, вы можете определить переменные локали сразу в команде SSH:
LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 ssh server.lan <command>
-
Использование другой оболочки: Если проблема связана с конкретной оболочкой, например, fish-шеллом, можно временно сменить оболочку или откорректировать её настройки. Например, временная смена оболочки на bash может устранить проблему.
Заключение
Проблема с локалью при использовании SSH с выполнением команд через командную строку возникает из-за различий между входными и обычными оболочками. Выбор подхода для решения этой проблемы зависит от вашего случая использования и требований к безопасности и совместимости. Воспользовавшись приведенными указаниями, вы сможете обеспечить корректное выполнение команд с нужными настройками локали.