Что проку от круглых скобок' ()' в определении функции оболочки?

Функция определяется как:

do_something () {
    do it
}

Я мог понять его имя 'do_something' и фигурная скобка для инкапсуляции кода действий, но не могу получить идею, из чего цель () здесь, с тех пор в сценариях Bash нет никаких именованных параметров. Это могло бы быть лучше и простым для определения его как

do_something {
  do it
}

Который не конфликтует с его текущим синтаксисом, и еще больше объявляет, что нет никаких именованных параметров. Из чего использование () здесь?

20
задан 11 April 2018 в 10:32

3 ответа

Без (), синтаксис действительно был бы неоднозначен.

Должен быть некоторый однозначный синтаксис для определения функции, и существенно не изменяя другой синтаксис оболочки, это не может быть это:

do_something {
    # one or more commands go here
}

Вы сказали, что это "не делает confict с его текущим синтаксисом", но он делает! Заметьте, что Вы не получаете вида синтаксической ошибки, когда Вы пытаетесь выполнить первую строку этого. Вы получаете ошибку, но это не ошибка о синтаксисе. Вторая строка, с }, синтаксическая ошибка, но первая строка не. Вместо этого do_something { попытки выполнить названную команду do_something и передача { как аргумент той команде:

$ do_something {
do_something: command not found

Если уже существует названная команда do_something, Вы выполняете его. Если уже существует вызванная функция do_something, Вы называете его. Важно в целом, чтобы синтаксис был однозначен, но также важно конкретно, чтобы было возможно переопределить функцию, случайно не называя его вместо этого. Определение функции и вызов ее не должны выглядеть одинаково.

Как оболочка рассматривает { и (.

Как type { скажет Вам, { ключевое слово оболочки. Это делает его как [[. Если бы используется в ситуации, где это иначе была бы команда, { несет специальную семантику. А именно, это выполняет группировку команды. В других ситуациях, однако, это может использоваться незавершенное для обозначения литерала { символ. Это включает ситуацию передачи его как вторая или последующая команда.

Конечно, Bash, возможно, был разработан для обработки { по-другому, чем он в настоящее время делает. Однако его синтаксис затем больше не был бы совместим с оболочкой POSIX, и Bash действительно не будет оболочкой стиля Границы и не был бы способен к выполнению многих сценариев оболочки.

Напротив, ( метасимвол оболочки. Это всегда рассматривают особенно, если это появляется в команде и не заключается в кавычки (с ' ', " ", или \). В синтаксисе нет таким образом никакой неоднозначности:

do_something() {
    # one or more commands go here
}

Это не могло означать ничто больше. Если бы Bash не имел функций, то это была бы синтаксическая ошибка по той же причине echo foo(bar) синтаксическая ошибка.

Если Вам действительно не нравится () нотация затем можно использовать ключевое слово function и опустите его, как sudodus упоминания. Обратите внимание, что это не часть синтаксиса для определения функций в большинстве других оболочек стиля Границы - и в некоторых, это поддерживается, но функции, определяемые, тот путь имеет другую семантику - и так сценарий, который использует его, не будут портативными. (Причина, этот синтаксис может быть однозначным, является этим function самостоятельно ключевое слово в Bash, который показывает, что независимо от того, что следует, это - запуск функционального определения.)

Наконец, обратите внимание на это, в то время как большинство функциональных определений использует { на практике любая составная команда разрешена. Если бы у Вас была функция, тело которой Вы хотели всегда выполнить в подоболочке, Вы могли использовать ( ) вместо { }.

44
ответ дан 23 November 2019 в 01:46

() маркер должен сказать интерпретатору оболочки об объявлении функции.

$ do_something () { echo 'do it'; } ; do_something
do it

Альтернатива в bash function

function do_something {
 echo 'do it'
}

или как острота можно протестировать

$ bash -c "function do_something { echo 'do it'; } ; do_something"
do it
15
ответ дан 23 November 2019 в 01:46

Как очень one-true-brace-style-ist Вас!

Рассмотрите другой, превосходные стили фигурной скобки:

foo
{
  ...
}
foo
  {
    ...
  }
foo
  while ...; do ...; done # Look, ma! No braces!
foo
( ... ) # Look, ma! No braces and a subshell to boot!

Как оболочка может сказать, что это - функциональные определения и не просто команда foo сопровождаемый списками команд? Во всех этих случаях, дополнительном факторе устранения неоднозначности, как () или function ключевое слово необходимо.

9
ответ дан 23 November 2019 в 01:46

Другие вопросы по тегам:

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