Может ли функция в sh иметь нулевые операторы?

Несколько ключей используются в качестве модификаторов ( shift , control являются наиболее используемый). Эмуляторы терминала получают серию событий X , которые вы можете увидеть с помощью xev . Эмулятор терминала объединяет некоторые из этих событий, такие как shift a , используя библиотеки X, чтобы получить A . Для других случаев, таких как функциональные клавиши и клавиши курсора (называемые «специальными клавишами» ), библиотеки X не имеют предопределенного преобразования. Эмулятор терминала решает, следует ли и когда использовать эти модификаторы для создания различных управляющих последовательностей, отправляемых специальными клавишами.

Различные эмуляторы терминала могут использовать для этого разные правила: не существует стандарта для последовательностей, которые могут быть отправлены. Есть только соглашения , например, решение имитировать определенные терминалы или расширять вещи путем создания новых последовательностей, чего не делает ни один другой терминал.

И rxvt, и xterm используют эти модификаторы для предоставления различных последовательностей функциональных клавиш, позволяя программам, работающим на терминалах, действовать так, как если бы у вашего терминала было несколько десятков функциональных клавиш.

Однако - терминалы также могут иметь режим , установленный управляющими последовательностями от приложения к терминалу, которые изменяют управляющие последовательности, отправляемые для функциональных клавиш. Эти последовательности управления переключением режимов обычно используются в полноэкранных программах (таких как vim).Итак, вы видите различия.

Поскольку не существует стандарта , для каждого терминала существует описание , которое описывает его поведение (с использованием переменной среды TERM ). Для большинства терминалов описание инициализирует терминал для использования прикладного режима (как для клавиатуры, так и для клавиш управления курсором). Полноэкранные приложения используют эти последовательности инициализации и используют функциональные клавиши и клавиши курсора, перечисленные в этих описаниях, чтобы обеспечить согласованное поведение.

Не все терминалы отправили escape-последовательности для функциональных клавиш. Например, рабочая станция altos использовала символ вставки, wyse-85 поддерживал 8-битный режим с использованием \ 233 вместо \ 033 [ (CSI), qnx использовал \ 377 . Но большинство начиналось с escape-символа ASCII. Финальные персонажи - это отдельная история. Около половины измененных функциональных клавиш rxvt оканчиваются символом, отличным от тильды ASCII ~ (в ncurses FAQ есть таблица, иллюстрирующая это). Из-за этих различий важно, чтобы описание терминала соответствовало фактическому терминалу.

В текущей версии vim (7.3) я не вижу проблем. Он распознает смещенный F8 . Несколько лет назад возникла проблема. Проверка vim на функциональные клавиши не ожидала точки с запятой, как это было отправлено xterm. Как только он заключил точку с запятой, он перестал распознавать функциональную клавишу.У вас может быть старая версия vim или некоторые сопоставления клавиш, которые мешают ему распознавать ключи. vim теперь может (в любой версии, которую вы используете), но не смотрел описание терминала для расширенных ключей, а полагался на свои собственные таблицы. Чтобы усложнить ситуацию, vim может использовать функцию xterm (называемую tcap-query ) для получения фактических ключевых последовательностей, отправленных xterm.

С другой стороны, vim, вероятно, имеет отображение, которое дает разные результаты для последовательностей ключей rxvt. Нет особого различия между его сдвинутым F6 ( \ E [29 ~ ), сдвинутым F7 ( \ E [31 ~ ) и сдвинул F8 ( \ E [32 ~ ).

Дополнительная литература:

3
08.03.2017, 01:43
3 ответа

Нет , функция не может иметь пустое тело между фигурными скобками в соответствующем приложении.


POSIX определяет команду определения функции как:

fname ( ) compound-command [io-redirect ...]

, где все эти слова являются заполнителями для вещей, определенных в другом месте спецификации. составная-команда является телом функции.

Составная команда определяется как один из нескольких элементов, включая циклы, условия и операторы case, но наиболее актуально здесь как команда группировки , который определяется в двух случаях :

(составной-список)

Выполнение составного-списка в среде подоболочки; см. Среда выполнения оболочки. Назначения переменных и встроенные команды, влияющие на среду, не должны оставаться в силе после завершения списка. ( ... отрывок об арифметическом раскрытии опущен ... )

{составной-список; }

Выполнить составной список в текущей среде процесса. Показанная здесь точка с запятой является примером оператора управления, ограничивающего зарезервированное слово}. Возможны и другие разделители, как показано в Грамматике оболочки; часто используется <новая строка>.

Пустое тело {\ n} было бы допустимым, если бы составной-список мог быть пустым.

Грамматика оболочки , в свою очередь, определяет правила синтаксического анализа командного языка оболочки, включая составной_лист :

 составной_лист: термин разрыва строки 
 | разделитель терминов переноса строки 
 

Это означает, что составной список представляет собой либо перенос строки , за которым следует термин , либо перенос строки , за которым следует терм и разделитель . разделитель - это ; или & . разрыв строки - это, возможно, пустая последовательность символов новой строки. Таким образом, он может быть пустым, если термин может быть пустым.

термин :

 термин: разделитель терминов and_or 
 | and_or 
 

и and_or :

 and_or: конвейер 
 | and_or AND_IF конвейер разрыва строки 
 | and_or OR_IF конвейер разрыва строки 
 

Последние две строки охватывают && и || . конвейер - это непустая последовательность команд , разделенных символами | . команда - это простая команда, составная команда или определение функции. Таким образом, term и command могут быть пустыми, если либо простые, либо составные команды могут быть пустыми.

Простая команда всегда включает одно из cmd_name , cmd_word или cmd_prefix . cmd_prefix - это либо перенаправление, либо назначение, необязательно присоединенное к другому префиксу. Два других разбиваются на WORD , лексему в грамматике, которая представляет собой непустую последовательность символов слова. Таким образом, простая команда никогда не бывает пустой.

Мы уже рассмотрели составные команды, но на этот раз давайте вернемся назад с точки зрения грамматики. Составная команда - это одна из фигурных скобок,подоболочка, для , while или до цикла , и if или случай . Все они содержат фиксированное слово (например, « вместо ») или ( или { как минимум. Таким образом, составная команда никогда не бывает пустой.

Таким образом, команда никогда не бывает пустой, поэтому pipeline никогда не бывает пустым, ни and_or , term , или complex_list . Это означает, что

{
}

не разрешен, и поэтому определение функции

a() {
}

также недействительно.


Все вышеперечисленное применимо для соответствующего переносимого сценария оболочки. zsh и ] ash могут по своему усмотрению расширять свои реализации для обработки недопустимых в противном случае скриптов, и выбранная ими реализация кажется разумной и удобной. Bash, ksh, dash и другие выбрали более минималистичный путь реализации того, что был обязательным. Все эти варианты являются совместимыми.

Переносимый сценарий всегда должен предоставлять непустое тело функции, но сценарий, ориентированный (скажем) только на zsh, этого не делает.

4
27.01.2020, 21:13

Это наиболее близкое к пустому значение, которое получает bash:

a (){  
  :   
}
0
27.01.2020, 21:13

Похоже, вас интересует синтаксическое дерево для различных оболочек. Вот соответствующий раздел для bash: https://www.gnu.org/software/bash/manual/bashref.html#Shell-Syntax

Функции определены как [ 1 ]:

Функции объявляются с использованием этого синтаксиса:
имя () составная-команда [перенаправления]
или
имя функции [()] составная-команда [перенаправления]

Интересующая вас часть представляет собой составную команду , которая может быть одной из следующих [ 2 ]:

• Конструкции цикла: команды оболочки для итеративного действия.
• Условные конструкции: команды оболочки для условного выполнения.
• Группировка команд: способы группировки команд.

Синтаксис {} и () представляет собой группу команд , которая может быть одной из следующих [ 3 ]:

(список)
{список; }

Список определяется как [ 4 ]:

Список - это последовательность из одного или нескольких конвейеров, разделенных одним из операторов ';' , '&' , '&&' или '||' , и необязательно завершается одним из ';' , '&' или перевод строки.

Конвейер определяется как [ 5 ]:

Конвейер - это последовательность из одной или нескольких команд, разделенных одним из операторов управления '|' или '| &' .

Примеры ваших функций содержат составную команду, которая должна содержать один или несколько конвейеров , каждый из которых содержит одну или несколько команд .

Следовательно, в bash у вас должна быть хотя бы одна команда в вашей функции. Другие оболочки, вероятно, похожи, и их руководства по синтаксису также легко доступны.

Если по какой-то причине вам нужна функция, которая ничего не делает, вы можете использовать встроенный в Bash заполнитель, которым является : - он ничего не делает успешно.

a(){:}
3
27.01.2020, 21:13

Теги

Похожие вопросы