Проверьте, не открыт ли порт приложениями, когда вы хотите его использовать.
Проверьте, нет ли сообщений в журнале ядра (используйте dmesg
).
Проверьте, что именно происходит в вашем приложении - запустите его под strace
, который сообщит о системных вызовах, которые делает приложение. Возможно, вы захотите использовать что-то вроде:
$ strace -f -s 512 -o /path/to/application.log.strace application ...
что также strace
дочерние процессы, строки журнала ap до их 512-го байта и все это окажется в /path/to/application.log.strace
, многоточие означает возможные аргументы для приложения. Вы также можете указать strace
прикрепляться к запущенному процессу, идентифицированному PID (аргумент -p
). Дополнительную информацию см. на странице strace(1)
. Ближе к концу журнала вы должны найти вызов write()
, который печатает сообщение об ошибке. Есть шанс, что относительно незадолго до этого будет open()
или write()
(на файле устройства), который вернул -1. Это может дать вам некоторое представление о причине ошибки.
В качестве примечания относительно прав доступа: вы не хотите использовать chmod 777
, поскольку это делает файл исполняемым, а это никогда не является хорошей идеей для чего-либо еще, кроме исполняемых файлов и каталогов. Для файлов устройств (в зависимости от их природы) разумными значениями являются 0640 или 0660, что позволяет полный доступ для root и доступ на чтение или чтение-запись для группы (членом которой должен быть данный пользователь, чтобы получить разрешения - в вашем случае это, вероятно, группа dialout
, которую вы упомянули).
В большинстве случаев вы также хотите добавить ноль (например, chmod 0664
, поскольку это удаляет любые биты suid, что обычно является хорошей идеей).
Вы правы в том, что назначение переменных оболочки LC_*
заставляет bash
вызывать POSIX setlocale()
для соответствующей категории со значением переменной независимо от того, экспортируются они или нет. Для LANG
он вызывает setlocale(LC_ALL, thevalue)
, а затем снова setlocale(LC_*)
для всех переменных LC_*
. Для LANGUAGE
это ничего не делает.
Итак, bash
— это оболочка проекта GNU. Для локализации текста используется GNU gettext
, также известный как libintl
. Он даже поставляется со своей собственной версией, связанной с исходным кодом, который вы можете скомпилировать в bash
, если вы вызовете скрипт configure
с --with-included-gettext
.
gettext
ищет переводы сообщений в базе данных для -языков. Какой это язык, определяется значением категории LC_MESSAGES
, хотя его можно переопределить переменной окружения $LANGUAGE
.
Согласно документации gettext, предыдущий вызов setlocale()
должен определять значение категории, но есть некоторые сложности:
Для многопоточных приложений в настоящее время нет стандартного API, который gettext может использовать для получения этого значения . bash
не является многопоточным приложением, но даже то, что возвращает setlocale(category, NULL)
, является реализацией определенной и на практике не всегда пригодной для использования .
Таким образом, на практике gettext использует setlocale()
только для получения имени языка при сборке как части библиотеки GNU libc или в системе, где libc является библиотекой GNU libc (, например той, которая была собрана с помощью bash
с --with-included-gettext
в системе GNU ), потому что знает, что на нее можно положиться.
В других системах он использует getenv()
для определения локали, независимо от того, как setlocale()
был вызван ранее, поэтому вы видите такое поведение.
Экспорт этих переменных легко обойти. Можно возразить, что если они не экспортируются, то они все равно не являются частью окружающей среды.POSIX не очень ясен в этом. Другой способ взглянуть на это заключается в том, что перевод выполняется не bash
, а сторонним механизмом, поэтому, как и при выполнении других команд, нам нужно использовать переменные среды для передачи информации о локали. между двумя программами (здесь bash
иgettext
).
Теперь, в системах GNU, все становится еще хуже.
Как показано выше, gettext включен в GNU libc. $LANGUAGE
имеет приоритет над $LC_MESSAGE
, но $LANGUAGE
не является частью API локали POSIX, это расширение поверх него.
Таким образом, в системе GNU gettext будет использовать setlocale(LC_MESSAGES, NULL)
для получения имени категории LC _MESSAGES, для LANGUAGE
всегда используется getenv()
, LANGUAGE
не является локалью.
Проблема в том, что bash
управляет средой сам по себе как часть своей обработки переменных, отключенной от массива environ[]
libc. У него есть собственный getenv()
, который запрашивает собственную версию среды, но когда gettext
создается как часть libc и bash
динамически компонуется, dgettext()
вызывает getenv()
из libc как это внутренний вызов внутри libc, а не bash
, поэтому будет получено значение $LANGUAGE
только с момента запуска bash
.
Таким образом, в системах GNU, если только bash
не была связана статически или не была создана с помощью --with-included-gettext
, любые изменения в $LANGUAGE
будут игнорироваться для сообщений, сгенерированных bash
, вне зависимости от того, экспортирована переменная или нет. В других системах это нормально (, если $LANGUAGE
экспортируется ), так как gettext не является частью libc, поэтому он вызывает bash
's getenv()
.
В Debian:
$ LANGUAGE=fr bash -c 'LANGUAGE=es; eval fi'
bash: eval: ligne 0: erreur de syntaxe près du symbole inattendu « fi »
bash: eval: ligne 0: `fi'
(сообщение на французском языке, значение $LANGUAGE
на момент вызова bash
, а не испанского ).
На самом деле с другими оболочками не намного лучше.
zsh
не переведен на другие языки, но использует strerror()
, который использует gettext
внутри систем GNU:
$ LANGUAGE=fr zsh -c 'LANGUAGE=es; true</x; LANGUAGE=en; true</a; true < /etc/shadow'
zsh:1: no existe el archivo o el directorio: /x
zsh:1: no existe el archivo o el directorio: /a
zsh:1: permission denied: /etc/shadow
LANGUAGE=es
было учтено, но обратите внимание, что второе сообщение для ENOENT не отображается на английском языке (, предположительно каким-то образом закэшированное gettext; этот кеш должен был стать недействительным при изменении $LANGUAGE
, но это было не так ).
Взгляните на этот ответ для объяснения разницы между переменной оболочки и переменной окружения. По существу:
Установка переменной оболочки:
LANG=en_US.UTF-8
Установка переменной окружения:
export LANG=en_US.UTF-8
Вы хотите установить переменные среды для локали, поскольку переменные оболочки являются частными для оболочки и не будут передаваться дочерним процессам.