Функции Bash

Thank you for reading this post, don't forget to subscribe!

Bash-функ­ция – это, по сути, набор команд, кото­рые мож­но вызы­вать мно­же­ство раз. Цель функ­ции – помочь вам сде­лать ваши bash-скрип­ты более чита­бель­ны­ми и избе­жать повтор­но­го напи­са­ния одно­го и того же кода.По срав­не­нию с боль­шин­ством язы­ков про­грам­ми­ро­ва­ния, функ­ции Bash доволь­но огра­ни­че­ны. В этой ста­тье мы рас­смот­рим осно­вы функ­ций Bash и пока­жем, как их исполь­зо­вать в сце­на­ри­ях оболочки.

 

Декларация функции Bash

Син­так­сис объ­яв­ле­ния функ­ции bash очень прост. Они могут быть объ­яв­ле­ны в двух раз­ных форматах:

  1. Пер­вый фор­мат начи­на­ет­ся с име­ни функ­ции, за кото­рым сле­ду­ют скоб­ки. Тело функ­ции долж­но быть заклю­че­но в фигур­ные скоб­ки {}.

     

    Одно­ли­ней­ная версия:

     

  2. Вто­рой фор­мат начи­на­ет­ся с заре­зер­ви­ро­ван­но­го сло­ва function, за кото­рым сле­ду­ет имя функ­ции. Фигур­ные скоб­ки {} не явля­ют­ся обязательными.

     

    Одно­ли­ней­ная версия:

     

Несколь­ко момен­тов, кото­рые сле­ду­ет отметить:

  • Спи­сок команд меж­ду фигур­ны­ми скоб­ка­ми {} – это тело функ­ции. Фигур­ные скоб­ки, кото­рые окру­жа­ют тело функ­ции, долж­ны быть отде­ле­ны от тела про­бе­ла­ми или сим­во­ла­ми новой строки.
  • Опре­де­ле­ние функ­ции не выпол­ня­ет ее. Что­бы вызвать функ­цию bash, про­сто исполь­зуй­те имя функ­ции. Коман­ды меж­ду фигур­ны­ми скоб­ка­ми выпол­ня­ют­ся вся­кий раз, когда функ­ция вызы­ва­ет­ся в сце­на­рии оболочки.
  • Опре­де­ле­ние функ­ции долж­но быть поме­ще­но перед любы­ми вызо­ва­ми функции.
  • При исполь­зо­ва­нии одно­строч­ных «уплот­нен­ных» функ­ций точ­ка с запя­той ;долж­на сле­до­вать за послед­ней коман­дой в функции.
  • Вы все­гда долж­ны ста­рать­ся, что­бы име­на ваших функ­ций были описательными.

Что­бы луч­ше это понять, взгля­нем на сле­ду­ю­щий пример:

~ / Hello_world.sh

 

Давай­те про­ана­ли­зи­ру­ем код построчно:

  • В стро­ке 3 мы опре­де­ля­ем функ­цию, при­сва­и­вая ей имя и откры­вая фигур­ную скоб­ку, { кото­рая обо­зна­ча­ет нача­ло тела функции.
  • Линия 4 – это тело функ­ции. Тело функ­ции может содер­жать несколь­ко команд.
  • Линия 5, закры­ва­ю­щая фигур­ная скоб­ка }, опре­де­ля­ет конец функ­ции hello_world.
  • В стро­ке 7 мы выпол­ня­ем функ­цию. Вы може­те выпол­нять функ­цию столь­ко раз, сколь­ко вам нужно.

Если вы запу­сти­те скрипт, он напе­ча­та­ет hello, world.

 

Гло­баль­ные пере­мен­ные – это пере­мен­ные, к кото­рым мож­но полу­чить доступ из любо­го места в скрип­те неза­ви­си­мо от обла­сти види­мо­сти. В Bash все пере­мен­ные по умол­ча­нию опре­де­ле­ны как гло­баль­ные, даже если они объ­яв­ле­ны внут­ри функции.

Локаль­ные пере­мен­ные могут быть объ­яв­ле­ны в теле функ­ции с клю­че­вым сло­вом local и могут исполь­зо­вать­ся толь­ко внут­ри этой функ­ции. Вы може­те иметь локаль­ные пере­мен­ные с оди­на­ко­вы­ми име­на­ми в раз­ных функциях.

Что­бы луч­ше про­ил­лю­стри­ро­вать, как рабо­та­ет область види­мо­сти пере­мен­ных в Bash, давай­те рас­смот­рим пример:

~ / Variables_scope.sh

 

Сце­на­рий начи­на­ет­ся с опре­де­ле­ния двух гло­баль­ных пере­мен­ных var1и var2. Затем функ­ция, уста­нав­ли­ва­ет локаль­ную пере­мен­ную var1 и изме­ня­ет гло­баль­ную пере­мен­ную var2.

Если вы запу­сти­те скрипт, вы долж­ны уви­деть сле­ду­ю­щий вывод:

 

Из при­ве­ден­но­го выше выво­да мож­но сде­лать вывод, что:

  • Если вы уста­но­ви­те локаль­ные пере­мен­ные внут­ри тела функ­ции с тем же име­нем, что и у суще­ству­ю­щей гло­баль­ной пере­мен­ной, она будет иметь при­о­ри­тет над гло­баль­ной переменной.
  • Гло­баль­ные пере­мен­ные могут быть изме­не­ны внут­ри функции.

 

Возвращаемые значения

В отли­чие от функ­ций в «реаль­ных» язы­ках про­грам­ми­ро­ва­ния, функ­ции Bash не поз­во­ля­ют вам воз­вра­щать зна­че­ние при вызо­ве. Когда функ­ция bash завер­ша­ет свою рабо­ту, ее воз­вра­ща­е­мое зна­че­ние явля­ет­ся состо­я­ни­ем послед­не­го опе­ра­то­ра, выпол­нен­но­го в функ­ции, 0 для успе­ха и нену­ле­во­го деся­тич­но­го чис­ла в диа­па­зоне 1 – 255 для отказа.

Ста­тус воз­вра­та мож­но ука­зать с помо­щью клю­че­во­го сло­ва return, и оно при­сва­и­ва­ет­ся пере­мен­ной $?. Опе­ра­тор return завер­ша­ет функ­цию. Вы може­те думать об этом как о состо­я­нии выхо­да из функции.

~ / Return_values.sh

 

 

Что­бы фак­ти­че­ски вер­нуть про­из­воль­ное зна­че­ние из функ­ции, нам нуж­но исполь­зо­вать дру­гие мето­ды. Самый про­стой вари­ант – при­сво­ить резуль­тат функ­ции гло­баль­ной переменной:

~ / Return_values.sh

 

 

Дру­гой, луч­ший вари­ант для воз­вра­та зна­че­ния из функ­ции – это отпра­вить зна­че­ние в stdout, исполь­зо­ва­ние echo или printf как пока­за­но ниже:

~ / Return_values.sh

 

 

Вме­сто того, что­бы про­сто выпол­нять функ­цию, кото­рая будет печа­тать сооб­ще­ние на стан­дарт­ный вывод, мы назна­ча­ем пере­мен­ную func_result с помо­щью меха­низ­ма $(). Исполь­зуя этот метод, пере­мен­ная func_result содер­жит резуль­тат функции.

 

Передача аргументов в функции Bash

Что­бы пере­дать любое коли­че­ство аргу­мен­тов функ­ции bash, про­сто поме­сти­те их сра­зу после име­ни функ­ции, раз­де­лив их про­бе­лом. Реко­мен­ду­ет­ся исполь­зо­вать двой­ные кавыч­ки аргу­мен­тов, что­бы избе­жать непра­виль­но­го раз­бо­ра аргу­мен­та с про­бе­ла­ми в нем.

  • Пере­да­ва­е­мые пара­мет­ры $1$2$3… $n, соот­вет­ству­ю­щее поло­же­нию пара­мет­ра после име­ни функции.
  • Пере­мен­ная $0 заре­зер­ви­ро­ва­на для име­ни функции.
  • Пере­мен­ная $# содер­жит чис­ло пози­ци­он­ных параметров/аргументов, пере­да­ва­е­мых функции.
  • Пере­мен­ная $* или $@ содер­жит все пози­ци­он­ные параметры/аргументы, пере­дан­ные функции.

Вот при­мер:

~ / Passing_arguments.sh