Процитированный вами отрывок не означает того, о чем вы говорите.
Шаблоны, совпадающие с одним символом
(...) Обычный символ - это шаблон, который должен совпадать сам с собой. (...) Если любой символ (обычный, shell special или pattern special) заключен в кавычки, то этот шаблон должен соответствовать самому символу.
Все это относится только к тем символам, которые стоят сами по себе в шаблоне. Это не относится к символам, которые появляются в другом контексте, чем тот, в котором ожидается появление символа шаблона. В частности, он не применяется внутри выражения со скобками. Синтаксис скобочных выражений описан в записи для [
:
Если открытая скобка вводит скобочное выражение, как в XBD RE Bracket Expression, (...)
(Я опустил часть про !
против ^
для дополнения). Описание выражений в квадратных скобках RE ничего не говорит о кавычках (что неудивительно, так как речь идет о выражениях в квадратных скобках вообще, а не о выражениях в шаблоне в скрипте оболочки).
Исходя из строгой интерпретации POSIX.1-2008, неясно, какому паттерну ["! "a"
должен соответствовать. Одна из интерпретаций заключается в том, что он должен совпадать с любым из символов "
, !
или a
: символ "
не имеет особого значения внутри выражения, заключенного в скобки. Я не могу найти в спецификации ничего, что сделало бы эту интерпретацию недействительной. Другая интерпретация заключается в том, что "
сохраняет свое поведение при цитировании, но это означает, что содержание заключенного в скобки выражения является !a
, и так как внутри заключенного в скобки выражения нет особого обращения с заключенными в кавычки символами, то набор является полностью но-a
. Я не могу найти никакой поддержки для вашей интерпретации (и поведения dash, bash и других оболочек) в спецификации POSIX. Конечно, это имеет смысл, но это не то, что написано в тексте.
Для будущей версии POSIX имело бы смысл дать мандат на вашу интерпретацию, добавив какую-нибудь формулировку на этот счет. Например, описание [
] может быть изменено на
Если открытая скобка вводит скобочное выражение, как в XBD RE Bracket Expression, за исключением того, что символ \ (
'! '
) должен заменить символ \ ('^'
) в его роли в несовпадающем списке в нотации регулярного выражения, он вводит шаблонное скобочное выражение, и что любой символ, который заключен в кавычки, должен стоять сам за себя как элемент заключающего скобочного выражения, элемента коллинга или выражения класса. Скобочное выражение, начинающееся с символа \ без кавычек, дает неопределенный результат. В противном случае,'[''
должно соответствовать самому символу.
Учитывая, что POSIX в основном носит описательный, а не нормативный характер, я бы ожидал, что такое изменение, ломающее ksh (обычно эталонную оболочку), будет включено только в крупное обновление стандарта, а любой дефект существующей версии будет вместо этого допускать по крайней мере существующие различные интерпретации.
Я не уверен, что понимаю источник вашего замешательства, но имейте в виду, что в Unix аргументы командной строки (foo
и bar
изecho foo bar
)и среда строки (FOO=bar
изenv - FOO=bar printenv
)просто копируются ядром в адресное пространство процесса, где к ним просто обращаются, как и к любой другой памяти (через указатели и т. д., );они не передаются как файлы, которые могут быть прочитаны, записаны или отображены в память процессом, как это делают стандартные stdin, stdout, stderr или любые дополнительные файловые дескрипторы.
Это не какой-то закон природы, это просто то, как это работает в Unix. Можно возразить, что это архаично, непоследовательно и неэффективно (— для каждого процесса создается копия всего окружения, даже если он игнорирует все или большую его часть ).
Различные меры могут быть сделаны --в plan9 , строки окружения на самом деле являются файлами в /env
(, что также означает, что они могут совместно использоваться между процессами ).
Кроме того, в Linux можно использовать хак LD_PRELOAD
, чтобы обойти ограничение argv+env, передав все это через файл, созданный с помощью memfd_create
.