Режим POSIX в Bash
Запуск Bash с опцией командной строки --posix или выполнение команды ‘set -o posix’ во время работы Bash приведет к тому, что Bash будет соответствовать стандарту POSIX более точно, изменив поведение для соответствия указанному в POSIX в тех областях, где поведение по умолчанию Bash отличается.
При вызове как sh, Bash переходит в режим POSIX после чтения стартовых файлов.
Ниже приведен список изменений, когда включен режим POSIX:
- Bash гарантирует, что переменная
POSIXLY_CORRECTустановлена. - Когда команда в таблице хешей больше не существует, Bash повторно ищет
$PATH, чтобы найти новое местоположение. Это также доступно с помощью ‘shopt -s checkhash’. - Bash не будет вставлять команду без установленного бита выполнения в таблицу хешей команд, даже если она возвращает ее в качестве (последнего) результата поиска
$PATH. - Сообщение, выводимое кодом управления заданиями и встроенными командами, когда задание завершается с ненулевым статусом, — это ‘Done(status)’.
- Сообщение, выводимое кодом управления заданиями и встроенными командами, когда задание приостановлено, — это ‘Stopped(signame)’, где signame — это, например,
SIGTSTP. - Расширение псевдонимов всегда включено, даже в неинтерактивных оболочках.
- Зарезервированные слова, появляющиеся в контексте, где распознаются зарезервированные слова, не подвергаются расширению псевдонимов.
- Расширение псевдонимов выполняется при первоначальном разборе подстановки команды. По умолчанию режим в основном откладывает его, когда он включен, до выполнения подстановки команды. Это означает, что подстановка команды не будет расширять псевдонимы, которые определены после того, как подстановка команды была первоначально обработана (например, в рамках определения функции).
- POSIX расширения ‘!’ до номера истории и ‘!!’ до ‘!’ включены, а расширение параметров выполняется по значениям
PS1иPS2независимо от настройки параметраpromptvars. - Файлы запуска POSIX выполняются (
$ENV) вместо обычных файлов Bash. - Расширение тильды выполняется только для присваиваний, предшествующих имени команды, а не для всех операторов присваивания в строке.
- Файл истории по умолчанию — ~/.sh_history (это значение по умолчанию для
$HISTFILE). - Операторы перенаправления не выполняют расширение имен файлов для слова в перенаправлении, если оболочка не интерактивна.
- Операторы перенаправления не выполняют разделение слов для слова в перенаправлении.
- Имена функций должны быть допустимыми именами оболочки
name. То есть они не могут содержать символы, отличные от букв, цифр и символов подчеркивания, и не могут начинаться с цифры. Объявление функции с недопустимым именем приводит к фатальной синтаксической ошибке в неинтерактивных оболочках. - Имена функций не могут совпадать с одним из специальных встроенных команд POSIX.
- Специальные встроенные команды POSIX находятся перед функциями оболочки во время поиска команды.
- При выводе определений функций оболочки (например, с помощью
type), Bash не выводит ключевое словоfunction. - Буквальные тильды, которые появляются в качестве первого символа в элементах переменной
PATH, не расширяются, как описано выше в разделе Расширение тильды. - Зарезервированное слово
timeможет использоваться само по себе как команда. При использовании таким образом оно отображает статистику времени выполнения оболочки и ее завершенных дочерних процессов. ПеременнаяTIMEFORMATуправляет форматом временной информации. - При разборе и расширении расширения ${…}, которое появляется в двойных кавычках, одинарные кавычки больше не являются специальными и не могут использоваться для заключения в кавычки закрывающей фигурной скобки или другого специального символа, если оператор не является одним из тех, которые определены для удаления шаблонов. В этом случае они не должны появляться в виде пар.
- Парсер не распознает
timeкак зарезервированное слово, если следующий токен начинается с ‘-’. - Символ ‘!’ не вводит расширение истории внутри строки в двойных кавычках, даже если опция
histexpandвключена. - Если специальная встроенная команда POSIX возвращает код ошибки, неинтерактивная оболочка завершается. Фатальные ошибки — те, которые перечислены в стандарте POSIX, и включают такие вещи, как передача неправильных параметров, ошибки перенаправления, ошибки присваивания переменных для присваиваний, предшествующих имени команды, и так далее.
- Неинтерактивная оболочка завершается с кодом ошибки, если возникает ошибка присваивания переменной, когда имя команды не следует за операторами присваивания. Ошибка присваивания переменной возникает, например, при попытке присвоить значение переменной только для чтения.
- Неинтерактивная оболочка завершается с кодом ошибки, если возникает ошибка присваивания переменной в операторе присваивания, предшествующем специальной встроенной команде POSIX, но не с любой другой простой командой. Для любой другой простой команды оболочка прерывает выполнение этой команды, и выполнение продолжается на верхнем уровне («оболочка не должна выполнять дальнейшей обработки команды, в которой произошла ошибка»).
- Неинтерактивная оболочка завершается с кодом ошибки, если переменная итерации в операторе
forили переменная выбора в оператореselectявляется переменной только для чтения. - Неинтерактивные оболочки завершаются, если filename в
.filename не найден. - Неинтерактивные оболочки завершаются, если синтаксическая ошибка в арифметическом расширении приводит к недопустимому выражению.
- Неинтерактивные оболочки завершаются, если возникает ошибка при расширении параметров.
- Неинтерактивные оболочки завершаются, если возникает синтаксическая ошибка в скрипте, прочитанном с помощью встроенных команд
.илиsource, или в строке, обработанной встроенной командойeval. - Хотя косвенное обращение к переменным доступно, оно не может применяться к специальным параметрам ‘#’ и ‘?’.
- Расширение специального параметра ‘*’ в контексте шаблона, где расширение заключено в двойные кавычки, не обрабатывает
$*как если бы оно было заключено в двойные кавычки. - Операторы присваивания, предшествующие специальным встроенным командам POSIX, сохраняются в среде оболочки после завершения встроенной команды.
- Встроенная команда
commandне предотвращает встроенные команды, которые принимают операторы присваивания в качестве аргументов, от расширения их как операторов присваивания; когда не в режиме POSIX, встроенные команды присваивания теряют свои свойства расширения операторов присваивания, когда предшествуютcommand. - Встроенная команда
bgиспользует требуемый формат для описания каждого задания, помещенного в фоновом режиме, который не включает указание того, является ли задание текущим или предыдущим. - Вывод ‘kill -l’ печатает все имена сигналов в одной строке, разделенные пробелами, без префикса ‘SIG’.
- Встроенная команда
killне принимает имена сигналов с префиксом ‘SIG’. - Встроенные команды
exportиreadonlyотображают свой вывод в формате, требуемом POSIX. - Встроенная команда
trapотображает имена сигналов без ведущего префиксаSIG. - Встроенная команда
trapне проверяет первый аргумент на возможное указание сигнала и не возвращает обработку сигнала к исходному состоянию, если это так, за исключением случаев, когда этот аргумент состоит только из цифр и является допустимым номером сигнала. Если пользователи хотят сбросить обработчик для данного сигнала до исходного состояния, они должны использовать ‘-’ в качестве первого аргумента. -
trap -pотображает сигналы, состояние обработки которых установлено в SIG_DFL, и те, которые были проигнорированы при запуске оболочки. - Встроенные команды
.иsourceне ищут файл в текущей директории, если он не найден при поиске вPATH. - Включение режима POSIX имеет эффект установки опции
inherit_errexit, поэтому дочерние оболочки, запущенные для выполнения подстановок команд, наследуют значение опции -e от родительской оболочки. Когда опцияinherit_errexitне включена, Bash очищает опцию -e в таких дочерних оболочках. - Включение режима POSIX имеет эффект установки опции
shift_verbose, поэтому числовые аргументы дляshift, превышающие количество позиционных параметров, приведут к сообщению об ошибке. - Когда встроенная команда
aliasвыводит определения псевдонимов, она не отображает их с ведущим ‘alias ’, если не указан параметр -p. - Когда встроенная команда
setвызывается без параметров, она не отображает имена и определения функций оболочки. - Когда встроенная команда
setвызывается без параметров, она отображает значения переменных без кавычек, если они не содержат метасимволы оболочки, даже если результат содержит непечатаемые символы. - Когда встроенная команда
cdвызывается в логическом режиме, и путь, построенный из$PWDи имени каталога, предоставленного в качестве аргумента, не ссылается на существующий каталог,cdзавершится ошибкой вместо перехода к физическому режиму. - Когда встроенная команда
cdне может изменить директорию, потому что длина пути, построенного из$PWDи имени каталога, предоставленного в качестве аргумента, превышаетPATH_MAXпри расширении всех символических ссылок,cdзавершится ошибкой вместо попытки использовать только предоставленное имя каталога. - Встроенная команда
pwdпроверяет, что выводимое значение совпадает с текущей директорией, даже если ей не задано проверять файловую систему с опцией -P. - При отображении истории встроенная команда
fcне включает указание того, была ли запись истории изменена. - Редактор по умолчанию, используемый
fc, —ed. - Встроенные команды
typeиcommandне будут сообщать о том, что невыполнимый файл найден, хотя оболочка попытается выполнить такой файл, если это единственный файл с таким именем, найденный в$PATH. - Режим редактирования
viбудет вызывать редакторviнапрямую при выполнении команды ‘v’ вместо проверки$VISUALи$EDITOR. - Когда опция
xpg_echoвключена, Bash не пытается интерпретировать какие-либо аргументы дляechoкак опции. Каждый аргумент отображается после преобразования управляющих символов. - Встроенная команда
ulimitиспользует размер блока 512 байт для опций -c и -f. - Появление
SIGCHLDпри установке ловушки наSIGCHLDне прерывает встроенную командуwaitи не заставляет ее возвращаться немедленно. Команда ловушки выполняется один раз для каждого дочернего процесса, который завершается. - Встроенную команду
readможно прервать сигналом, для которого установлена ловушка. Если Bash получает пойманный сигнал во время выполненияread, обработчик ловушки выполняется, иreadвозвращает код выхода больше 128. - Встроенная команда
printfиспользуетdouble(черезstrtod) для преобразования аргументов, соответствующих спецификаторам с плавающей точкой, вместоlong double, если оно доступно. Модификатор длины ‘L’ принудительно заставляетprintfиспользоватьlong double, если оно доступно. - Bash удаляет статус завершенного фонового процесса из списка таких статусов после использования встроенной команды
waitдля его получения.
Существует другое поведение POSIX, которое Bash не реализует по умолчанию, даже когда включен режим POSIX. В частности:
- Встроенные проверки
fcпроверяют$EDITORкак программу для редактирования записей истории, еслиFCEDITне задано, вместо непосредственного использования значения по умолчаниюed.fcиспользуетedеслиEDITORне задано. - Как указано выше, Bash требует включения опции
xpg_echoдля того, чтобы встроенная команда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