Spec-Zone.ru › Bash

Bash и POSIX

  • Что такое POSIX?
  • Режим POSIX в Bash

6.11.1 Что такое POSIX?

​

POSIX — это название семейства стандартов, основанных на Unix. В стандарт входит ряд служб, инструментов и функций Unix — от базовых системных вызовов и функций библиотеки C до распространённых приложений и инструментов системного администрирования и управления.

Стандарт POSIX Shell and Utilities первоначально разработала рабочая группа IEEE 1003.2 (POSIX.2). Первое издание стандарта 1003.2 было опубликовано в 1992 году. Эта группа объединилась с первоначальной рабочей группой IEEE 1003.1; в настоящее время стандарт поддерживает группа Austin (совместная рабочая группа IEEE, The Open Group и ISO/IEC SC22/WG15). Сегодня Shell and Utilities — это том из набора документов, составляющих IEEE Std 1003.1-2024, поэтому прежний POSIX.2 (от 1992 года) теперь является частью действующего объединённого стандарта POSIX.

Том Shell and Utilities посвящён интерфейсу командного интерпретатора и служебным программам, которые обычно запускаются из командной строки или другими программами. Стандарт доступен в интернете бесплатно по адресу https://pubs.opengroup.org/onlinepubs/9799919799/utilities/contents.html.

Bash учитывает аспекты поведения оболочки, определённые томом POSIX Shell and Utilities. Разумеется, стандартизирован язык команд оболочки, включая основные конструкции управления потоком и выполнения программ, перенаправление ввода-вывода и конвейеры, обработку аргументов, подстановку переменных и экранирование.

Специальные встроенные команды, которые должны быть реализованы в составе оболочки для обеспечения требуемой функциональности, определены как часть оболочки; к ним относятся, например, eval и export. Другие утилиты описаны в разделах POSIX, не посвящённых оболочке, но обычно (а в некоторых случаях обязательно) реализуются как встроенные команды, например read и test. POSIX также определяет некоторые аспекты интерактивного поведения оболочки, включая управление заданиями и редактирование командной строки. Стандартизированы только команды редактирования строк в стиле vi; команды редактирования в стиле Emacs не включили из-за возражений.

6.11.2 Режим POSIX в Bash

​

Хотя Bash реализует спецификацию оболочки POSIX, в некоторых случаях поведение Bash по умолчанию отличается от спецификации. Режим POSIX Bash изменяет поведение в этих случаях, чтобы оно точнее соответствовало стандарту.

Если запустить Bash с параметром командной строки --posix или выполнить команду ‘set -o posix’ во время работы Bash, он будет точнее соответствовать стандарту POSIX: поведение Bash изменится и будет соответствовать требованиям POSIX в тех случаях, где поведение Bash по умолчанию отличается.

При запуске в качестве sh Bash переходит в режим POSIX после чтения файлов запуска.

Ниже перечислены изменения, действующие в режиме POSIX:

  1. Bash гарантирует, что переменная POSIXLY_CORRECT установлена.
  2. Bash читает и выполняет файлы запуска POSIX ($ENV), а не обычные файлы Bash (см. Файлы запуска Bash.
  3. Подстановка псевдонимов всегда включена, в том числе в неинтерактивных оболочках.
  4. Зарезервированные слова, встречающиеся в контексте, где распознаются зарезервированные слова, не подвергаются подстановке псевдонимов.
  5. Подстановка псевдонимов выполняется при первоначальном разборе подстановки команды. В режиме по умолчанию (не POSIX) она обычно откладывается, если включена, до выполнения подстановки команды. Это означает, что при подстановке команды не будут подставляться псевдонимы, определённые после её первоначального разбора (например, при определении функции).
  6. Зарезервированное слово time можно использовать самостоятельно в качестве простой команды. В таком виде оно выводит статистику времени для оболочки и завершившихся дочерних процессов. Формат сведений о времени задаётся переменной TIMEFORMAT.
  7. Анализатор не распознаёт time как зарезервированное слово, если следующий токен начинается с ‘-’.
  8. При разборе и подстановке конструкции ${…}, находящейся внутри двойных кавычек, одинарные кавычки больше не являются специальными символами и не могут использоваться для экранирования закрывающей фигурной скобки или другого специального символа, если только оператор не относится к операторам удаления шаблонов. В этом случае одинарные кавычки не обязательно должны образовывать пару.
  9. Операторы перенаправления не выполняют подстановку имён файлов для слова в перенаправлении, если оболочка не является интерактивной.
  10. Операторы перенаправления не выполняют разделение слов для слова в перенаправлении.
  11. Имена функций не могут совпадать с именами специальных встроенных команд POSIX.
  12. Подстановка тильды выполняется только для присваиваний, предшествующих имени команды, а не для всех операторов присваивания в строке.
  13. Хотя косвенное обращение к переменным доступно, его нельзя применять к специальным параметрам ‘#’ и ‘?’.
  14. При подстановке специального параметра ‘*’ в контексте шаблона, когда подстановка заключена в двойные кавычки, $* не рассматривается как заключённый в двойные кавычки.
  15. Символ двойной кавычки (‘"’) обрабатывается особым образом, если он встречается в подстановке команды с обратными кавычками внутри тела расширяемого документа here-doc. Это означает, например, что обратная косая черта перед двойной кавычкой экранирует её и удаляется.
  16. Подстановки команд не устанавливают специальный параметр ‘?’. Код завершения простой команды без слова команды по-прежнему равен коду завершения последней подстановки команды, выполненной при вычислении присваиваний переменных и перенаправлений в этой команде, но это происходит только после всех присваиваний и перенаправлений.
  17. Буквальные тильды, стоящие первыми символами элементов переменной PATH, не подставляются, как описано выше в разделе Подстановка тильды.
  18. При поиске команд специальные встроенные команды POSIX имеют приоритет перед функциями оболочки, в том числе при выводе командами type и command.
  19. Даже если функция оболочки, имя которой содержит косую черту, была определена до перехода в режим POSIX, оболочка не будет выполнять функцию, имя которой содержит одну или несколько косых черт.
  20. Если команда из хеш-таблицы больше не существует, Bash повторно выполнит поиск в $PATH, чтобы найти её новое расположение. Это поведение также можно включить командой ‘shopt -s checkhash’.
  21. Bash не будет добавлять в хеш-таблицу команду без установленного бита выполнения, даже если она возвращается в качестве последнего возможного результата поиска $PATH.
  22. Сообщение, выводимое кодом управления заданиями и встроенными командами при завершении задания с ненулевым статусом, — ‘Done(status)’.
  23. Сообщение, выводимое кодом управления заданиями и встроенными командами при приостановке задания, — ‘Stopped(signame)’, где signame — это, например, SIGTSTP.
  24. Если оболочка интерактивна, Bash не выводит уведомления о заданиях между выполнением команд в списках, разделённых символом ‘;’ или переводом строки. Неинтерактивные оболочки выводят сообщения о состоянии после завершения команды переднего плана в списке.
  25. Если оболочка интерактивна, Bash ждёт следующего приглашения, прежде чем вывести состояние фонового задания, состояние которого изменилось, или задания переднего плана, завершившегося из-за сигнала. Неинтерактивные оболочки выводят сообщения о состоянии после завершения задания переднего плана.
  26. Bash окончательно удаляет задания из таблицы заданий после уведомления пользователя об их завершении с помощью встроенных команд wait или jobs. Задание удаляется из списка заданий после уведомления пользователя о завершении, однако его статус по-прежнему доступен через wait, если команде wait передан аргумент PID.
  27. В режиме редактирования vi команда ‘v’ напрямую запускает редактор vi, не проверяя $VISUAL и $EDITOR.
  28. При раскрытии приглашения включается раскрытие POSIX PS1 и PS2: ‘!’ заменяется номером в истории, а ‘!!’ — на ‘!’. Bash выполняет подстановку параметров для значений PS1 и PS2 независимо от состояния параметра promptvars.
  29. Файл истории по умолчанию — ~/.sh_history (это значение, которое оболочка по умолчанию присваивает переменной $HISTFILE).
  30. Символ ‘!’ не запускает подстановку из истории внутри строки в двойных кавычках, даже если включён параметр histexpand.
  31. При выводе определений функций оболочки (например, командой type) Bash не выводит зарезервированное слово function, если в этом нет необходимости.
  32. Неинтерактивные оболочки завершают работу, если синтаксическая ошибка в арифметическом выражении приводит к недопустимому выражению.
  33. Неинтерактивные оболочки завершают работу при ошибке подстановки параметра.
  34. Если специальная встроенная команда POSIX возвращает статус ошибки, неинтерактивная оболочка завершается. К фатальным относятся ошибки, перечисленные в стандарте POSIX, например передача недопустимых параметров, ошибки перенаправления, ошибки присваивания переменных в присваиваниях перед именем команды и т. д.
  35. Неинтерактивная оболочка завершается с ошибочным статусом, если возникает ошибка присваивания переменной и за операторами присваивания не следует имя команды. Например, ошибка присваивания возникает при попытке присвоить значение переменной, доступной только для чтения.
  36. Неинтерактивная оболочка завершается с ошибочным статусом, если ошибка присваивания переменной возникает в операторе присваивания перед специальной встроенной командой, но не перед какой-либо другой простой командой. Для любой другой простой команды оболочка прерывает выполнение этой команды, а выполнение продолжается на верхнем уровне («оболочка не должна выполнять дальнейшую обработку команды, в которой произошла ошибка»).
  37. Неинтерактивная оболочка завершается с ошибочным статусом, если переменная итерации в операторе for или переменная выбора в операторе select доступна только для чтения или имеет недопустимое имя.
  38. Неинтерактивные оболочки завершают работу, если файл filename в . filename не найден.
  39. Неинтерактивные оболочки завершают работу при синтаксической ошибке в скрипте, прочитанном встроенными командами . или source, либо в строке, обработанной встроенной командой eval.
  40. Неинтерактивные оболочки завершают работу, если встроенные команды export, readonly или unset получают аргумент, не являющийся допустимым идентификатором, и не работают с функциями оболочки. Эти ошибки приводят к завершению работы, поскольку это специальные встроенные команды.
  41. Операторы присваивания перед специальными встроенными командами POSIX сохраняются в окружении оболочки после завершения встроенной команды.
  42. Встроенная команда command не препятствует встроенным командам, принимающим операторы присваивания в качестве аргументов, обрабатывать их как операторы присваивания; вне режима POSIX команды объявления теряют свойства обработки операторов присваивания, если перед ними указана command.
  43. Включение режима POSIX приводит к установке параметра inherit_errexit, поэтому подоболочки, запускаемые для выполнения подстановок команд, наследуют значение параметра -e родительской оболочки. Если параметр inherit_errexit не включён, Bash сбрасывает параметр -e в таких подоболочках.
  44. Включение режима POSIX приводит к установке параметра shift_verbose, поэтому числовые аргументы команды shift, превышающие количество позиционных параметров, вызывают сообщение об ошибке.
  45. Включение режима POSIX приводит к установке параметра interactive_comments (см. Комментарии).
  46. Встроенные команды . и source не ищут файл-аргумент в текущем каталоге, если он не найден при поиске в PATH.
  47. При выводе определений псевдонимов встроенная команда alias не добавляет в начало ‘alias ’, если не указан параметр -p.
  48. Встроенная команда bg использует требуемый формат для описания каждого задания, помещённого в фоновый режим; в нём не указывается, является ли задание текущим или предыдущим.
  49. Если встроенная команда cd вызвана в логическом режиме и путь, сформированный из $PWD и переданного в качестве аргумента имени каталога, не указывает на существующий каталог, cd завершится ошибкой, а не переключится на физический режим.
  50. Если встроенная команда cd не может сменить каталог, поскольку длина пути, сформированного из $PWD и переданного в качестве аргумента имени каталога, после канонизации превышает PATH_MAX, команда cd попытается использовать переданное имя каталога.
  51. Если включён параметр xpg_echo, Bash не пытается интерпретировать аргументы echo как параметры. echo выводит каждый аргумент после преобразования escape-последовательностей.
  52. Встроенные команды export и readonly выводят результат в формате, требуемом POSIX.
  53. При выводе списка истории встроенная команда fc не указывает, изменялась ли запись истории.
  54. Редактор по умолчанию, используемый командой fc, — ed.
  55. fc считает лишние аргументы ошибкой, а не игнорирует их.
  56. Если команде fc -s передано слишком много аргументов, fc выводит сообщение об ошибке и возвращает ошибочный статус.
  57. Команда ‘kill -l’ выводит имена всех сигналов в одну строку через пробел, без префикса ‘SIG’.
  58. Встроенная команда kill не принимает имена сигналов с префиксом ‘SIG’.
  59. Встроенная команда kill возвращает ошибочный статус, если какой-либо аргумент pid или задание недопустимы либо если не удаётся отправить указанный сигнал какому-либо из них. В режиме по умолчанию kill возвращает успешный статус, если сигнал удалось отправить хотя бы одному из указанных процессов.
  60. Встроенная команда printf использует double (через strtod) для преобразования аргументов, соответствующих спецификаторам преобразования чисел с плавающей точкой, вместо long double, если эта функция доступна. Модификатор длины ‘L’ заставляет printf использовать long double, если эта функция доступна.
  61. Встроенная команда pwd проверяет, совпадает ли выводимое значение с текущим каталогом, даже если её не просят проверять файловую систему с помощью параметра -P.
  62. Встроенная команда read может быть прервана сигналом, для которого задан обработчик. Если Bash получает перехваченный сигнал во время выполнения read, запускается обработчик сигнала, а read возвращает код завершения больше 128.
  63. Если встроенная команда set вызвана без параметров, она не выводит имена и определения функций оболочки.
  64. Если встроенная команда set вызвана без параметров, она выводит значения переменных без кавычек, если только они не содержат метасимволы оболочки, даже если результат содержит непечатаемые символы.
  65. При вычислении бинарных операторов ‘<’ и ‘>’ встроенная команда test сравнивает строки с учётом текущей локали.
  66. Унарный первичный оператор -t встроенной команды test требует аргумент. В исторических версиях test в некоторых случаях аргумент был необязательным; Bash пытается поддерживать это для обратной совместимости.
  67. Встроенная команда trap выводит имена сигналов без начального SIG.
  68. Встроенная команда trap не проверяет, может ли первый аргумент задавать сигнал, и не восстанавливает исходный способ обработки сигнала, если это так, за исключением случая, когда аргумент состоит только из цифр и является допустимым номером сигнала. Чтобы сбросить обработчик указанного сигнала и восстановить исходный способ обработки, следует указать ‘-’ в качестве первого аргумента.
  69. trap -p без аргументов выводит сигналы, для которых задан SIG_DFL, и сигналы, игнорировавшиеся при запуске оболочки, а не только сигналы с заданными обработчиками.
  70. Встроенные команды type и command не сообщают, что неисполняемый файл найден, хотя оболочка попытается выполнить такой файл, если это единственный файл с таким именем, найденный в $PATH.
  71. Встроенная команда ulimit использует размер блока 512 байт для параметров -c и -f.
  72. Встроенная команда unset с указанным параметром -v возвращает фатальную ошибку при попытке удалить переменную readonly или non-unsettable, что приводит к завершению неинтерактивной оболочки.
  73. При удалении переменной, указанной в операторе присваивания перед командой, встроенная команда unset также пытается удалить одноимённую переменную в текущей или предыдущей области видимости. Это реализует требуемое поведение: «если присвоенная переменная далее изменяется утилитой, изменения, внесённые утилитой, должны сохраняться».
  74. Поступление SIGCHLD при установленном обработчике для SIGCHLD не прерывает встроенную команду wait и не заставляет её немедленно завершиться. Команда обработчика сигнала выполняется при завершении каждого дочернего процесса.
  75. После того как встроенная команда wait возвращает статус завершившегося фонового процесса, Bash удаляет этот статус из списка таких статусов.

В Bash есть дополнительное поведение POSIX, которое по умолчанию не реализовано даже в режиме POSIX. В частности:

  1. POSIX требует побайтового разделения слов. То есть каждый байт в значении IFS потенциально может разделять слово, даже если этот байт является частью многобайтового символа в IFS или частью многобайтового символа в самом слове. Bash допускает многобайтовые символы в значении IFS, рассматривая допустимый многобайтовый символ как единый разделитель, и не разделяет допустимый многобайтовый символ, даже если один из составляющих его байтов присутствует в IFS. Это трактовка POSIX 1560, дополнительно изменённая в соответствии с issue 1924.
  2. Встроенная команда fc использует $EDITOR в качестве программы для редактирования записей истории, если FCEDIT не задана, вместо того чтобы сразу выбирать ed по умолчанию. fc использует ed, если EDITOR не задана.
  3. Как отмечалось выше, для полного соответствия встроенной команды echo Bash требует включить параметр xpg_echo.

Bash можно настроить так, чтобы он по умолчанию соответствовал POSIX, указав параметр --enable-strict-posix-default для configure при сборке (см. Необязательные возможности).

Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API