Режим Force POSIX

Расширение Brace, например {a, b, c}, не определяется POSIX . Я хотел бы запустить свою оболочку в режиме POSIX. С Debian это достаточно просто:

$ bash -c 'echo {a,b,c}' abc $ sh -c 'echo {a,b,c}' {a,b,c} 

Однако Fedora ведет себя по-другому:

 $ bash -c 'echo {a,b,c}' abc $ sh -c 'echo {a,b,c}' abc 

Я попытался использовать --posix , но он не имеет никакого эффекта:

 $ sh --posix -c 'echo {a,b,c}' abc 

Может ли Bash принудительно работать в режиме POSIX?

Bash можно сказать, чтобы отключить расширение скобки с помощью set +B , который является обратным для set -B :

-B Оболочка будет выполнять расширение скобки (см. Расширение Brace ). Этот параметр включен по умолчанию.

Вы также можете предоставить это в командной строке при запуске оболочки:

 $ bash +B -c 'echo {a,b,c}' {a,b,c} 

Вы можете комбинировать это с --posix set -o posix или set -o posix , чтобы приблизиться к поведению полностью POSIX. Вам также необходимо включить shopt -s xpg_echo как минимум.

Будут и другие углы – многие из расширений довольно глубоко укоренились – и я не думаю, что можно заставить Баша поддерживать только поведение, которое на самом деле было поручено POSIX. Даже dash это не удается.

Тем не менее, вы можете найти dash (по умолчанию /bin/sh на Debian) более полезно, если вы стремитесь избегать расширенного поведения, хотя оно поддерживает некоторые расширения. Существует также апплет ashy BusyBox , который также имеет некоторые расширения, но многие могут быть отключены статически.

В соответствии с Справочным руководством Bash ( http://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html ) флаг --posix приведет к тому, что Bash будет более тесно соответствовать POSIX стандарт». Кажется, полное соответствие POSIX не является вариантом.

Что касается разницы в поведении, я считаю, что вы найдете /bin/sh символическая ссылка на /bin/bash на Fedora. Возможно, у Debian есть реализация non-bash для /bin/sh .

По умолчанию Debian, sh – это ссылка на dash (не bash ). Dash больше подходит для поведения POSIX для «расширения брекетов».

У Bash есть эта документированная разница с историческим sh (от man bash):

Расширение брекета представляет собой небольшую несовместимость с историческими версиями sh. sh не обрабатывает открывающие или закрывающие фигурные скобки специально, когда они появляются как часть слова и сохраняет их на выходе. Bash удаляет фигурные скобки из слов как следствие расширения скобки. Например, слово, введенное в sh как файл {1,2}, отображается на выходе идентично. Это же слово выводится как file1 file2 после расширения bash. Если требуется строгая совместимость с sh, запустите bash с опцией + B или отключите расширение скобки с помощью опции + B в команде set.

Любая из этих работ:

 bash +B -c 'echo {a,b,c}' bash -c 'set +B; echo {a,b,c}' 

И, если вам все еще нужно больше POSIXly bash:

 bash --posix +B -c 'echo {a,b,c}' bash --posix -c 'set +B; echo {a,b,c}' 

Поскольку изменение оболочки по умолчанию для /bin/sh имеет много последствий для всей системы, я не рекомендую вам менять /bin/sh на dash .

Тем не менее, как правило, $HOME/bin/ (или aka ~/bin/ ) устанавливается перед /bin/ в PATH. Таким образом, вы можете скопировать исполняемый файл dash на ваш пользователь ~/bin/sh (или даже символическую или реальную ссылку), и тире будет работать по умолчанию для этого пользователя.

Иногда включение ~/bin/ в исполняемые программы пользователя выполняется в .profile :

 [ -d "${HOME}/bin" ] && export PATH="${HOME}/bin:$PATH" 

который получает (почти любая оболочка) bash при первом входе в систему (на момент запуска сервера X для пользователя), и с этого момента он существует как значение среды.

Если это существует, все, что вам нужно сделать, это создать каталог /home/$USER/bin .
Конечно, вам нужно снова войти в систему или исходный ~/.profile .