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

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

Подобно "настоящим" языкам программирования, Bash тоже имеет функции, хотя и в несколько ограниченном варианте. Функция — это подпрограмма, блок кода который реализует набор операций, своего рода "черный ящик" , предназначенный для выполнения конкретной задачи. Функции могут использоваться везде, где имеются участки повторяющегося кода.

Вторая форма записи ближе к сердцу C-программистам (она же более переносимая).

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

Вызов функции осуществляется простым указанием ее имени в тексте сценария.

Пример 22-1. Простая функция

Функция должна быть объявлена раньше, чем ее можно будет использовать. К сожалению, в Bash нет возможности "опережающего объявления" функции, как например в C.

Допускается даже создание вложенных функций, хотя пользы от этого немного.

Объявление функции может размещаться в самых неожиданных местах.

Функции могут принимать входные аргументы и возвращать код завершения.

Доступ к входным аргументам, в функциях, производится посредством позиционных параметров, т.е. $1, $2 и так далее.

Пример 22-2. Функция с аргументами

Команда shift вполне применима и к аргументам функций (см. Пример 33-10).

В отличие от других языков программирования, в сценариях на языке командной оболочке, в функции передаются аргументы по значению. [1] Если имена переменных (которые фактически являются указателями) передаются функции в виде аргументов, то они интерпретируются как обычные строки символов и не могут быть разыменованы. Функции интерпретируют свои аргументы буквально.

Exit и Return

Функции возвращают значение в виде кода завершения. Код завершения может быть задан явно, с помощью команды return, в противном случае будет возвращен код завершения последней команды в функции ( 0 — в случае успеха, иначе — ненулевой код ошибки). Код завершения в сценарии может быть получен через переменную $?.

Завершает исполнение функции. Команда return [2] может иметь необязательный аргумент типа integer , который возвращается в вызывающий сценарий как "код завершения" функции, это значение так же записывается в переменную $?.

Пример 22-3. Наибольшее из двух чисел

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

Пример 22-4. Преобразование чисел в римскую форму записи

Наибольшее положительное целое число, которое может вернуть функция — 255. Команда return очень тесно связана с понятием код завершения, что объясняет это специфическое ограничение. К счастью существуют различные способы преодоления этого ограничения.

Пример 22-5. Проверка возможности возврата функциями больших значений

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

Еще один способ — использовать глобальные переменные для хранения "возвращаемого значения" .

Пример 22-6. Сравнение двух больших целых чисел

Упражнение: Используя только что полученные знания, добавьте в предыдущий пример, преобразования чисел в римскую форму записи, возможность обрабатывать большие числа.

Перенаправление

Перенаправление ввода для функций

Функции — суть есть блок кода, а это означает, что устройство stdin для функций может быть переопределено (перенаправление stdin) (как в Пример 3-1).

Пример 22-7. Настоящее имя пользователя

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

Примечания

Механизм косвенных ссылок на переменные (см. Пример 34-2) слишком неудобен для передачи аргументов по ссылке.

Команда return — это встроенная команда Bash.

есть функция например

можно ли сделать вот так ?

3 ответа 3

Можно передавать параметры.
Вызов будет:

А обращение к параметрам

Функция обращается к переданным ей аргументам основываясь на их позиции. Т.е. это позиционные параметры

вообще информацию в функцию (и в сам скрипт в том числе) можно передавать (как минимум) четырьмя путями:

  1. аргументами (позиционными параметрами)
  2. переменными окружения
  3. содержимым стандартного потока ввода stdin
  4. содержимым файлов

вот скрипт, демонстрирующий первые три пути:

вот результат его запуска:

Нет, ну передачей аргументов в функцию собственно называется передача их в списке вызова, а не как-то ещё. Внешние аргументы, интерактивное чтение из stdin или другого файла — это не передача данных в функцию, а способ получения данных независимо от того, где этот код написан. Автор видимо не понимает, что это такое — передача аргументов в функцию. ну да ладно! Так что из его 4-х способов фактически остаётся только 1 — позиционные параметры. Вопрос состоял в том, можно ли передавать именованные параметры. Ответ — нет. Это не предусмотрено в современном синтаксисе bash скрипта. Может быть в последующих версиях.

Количество параметров — тоже не слишком много. Это не мильён точно. Но штук 20 передать можно. Я больше не пробовал. Вы можете проверить. Но боюсь это не стабильный параметр. Определены так же переменные $# — кол-во аргументов и список $@. Параметр $0, тем не менее, означает не имя функции, как могло бы показаться, а имя скрипта. Это отличие! Эти аргументы не readonly. Т.е. вы их можете менять, сдвигать список с помощью shift . правда на внешнем окружении это не скажется. Сложно будет даже синтаксически поменять позиционный параметр, ибо по правилам синтаксиса bash вам придётся записать что-то типа 1=новое_значение , что немедленно вызовет ошибку, ибо 1 будет восприниматься не как имя переменной, а как число. Странно что это не заложено в синтаксисе. Но если использовать eval , то можно. Но не нужно, кроме случая, если вы не используете ещё один способ передачи аргумента в функцию: косвенную ссылку с изменением её значения внутри функции.

В целом такой механизм bash не предусматривает, но запрета нет. Поэтому путём манипуляций вы это можете проделать. Хотя это скорей похоже не на нормальный код, а на некое шаманство. Но всё же работает. Код плохо понимаем, но так можно делать. Это не для новичков, говорю сразу. Было бы забавно, если бы конструкция типа 1=verry сработала, в смысле что мы умудрились поменять само число 1. Я не знаю, как стала бы работать после этого программа, скорей всего никак, или началась бы жутко непонятное поведение. Это конечно недопустимо, единицу менять нельзя. А такое в практике программирования встречалось уже. Помню в первых версиях фортрана можно было поменять даже ноль. Программа просто вылетала! Причём совершенно непонятно почему. Как говорится всяко бывает.

676 stivlo [2011-06-02 11:35:00]

Я пытаюсь найти, как передавать параметры в функции Bash, но то, что появляется, всегда — как передать параметр из командной строки.

Я хотел бы передать параметры в моем script. Я пробовал:

Но синтаксис неверен, как передать параметр моей функции?

7 ответов

1178 Решение dogbane [2011-06-02 11:57:00]

Существует два типичных способа объявления функции. Я предпочитаю второй подход.

Чтобы вызвать функцию с аргументами:

Функция ссылается на переданные аргументы по их позиции (не по имени), то есть $ 1, $ 2 и т.д. $ 0 — это имя самого скрипта.

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

Вывод:

Знание языков программирования высокого уровня (C/C++/Java/PHP/Python/Perl. ) предложило бы непрофессионалу, что функции bash должны работать так же, как на других языках. Вместо этого функции bash работают как команды оболочки и ожидают, что аргументы будут переданы им так же, как можно передать параметр команде оболочки (ls -l). По сути, аргументы функции в bash рассматриваются как позиционные параметры ( $1, $2..$9, $<10>, $ <11>и т.д.). Это неудивительно, учитывая, как работает getopts . Круглые скобки не обязаны вызывать функцию в bash.

(Примечание. В настоящий момент я работаю над Open Solaris.)

Пропустите параны и запятые:

и функция должна выглядеть так:

24 niieani [2015-05-04 18:23:00]

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

Метод, который я разработал, позволяет вам определить именованные параметры, переданные такой функции:

Вы также можете аннотировать аргументы как @required или @readonly, создавать. остальные аргументы, создавать массивы из последовательных аргументов (используя, например, string[4] ), и дополнительно перечислять аргументы в нескольких строках:

Другими словами, вы можете не только вызывать свои параметры по их именам (что составляет более читаемое ядро), вы можете фактически передавать массивы (и ссылки на переменные — эта функция работает только в bash 4.3)! Кроме того, отображаемые переменные находятся в локальной области, как и $ 1 (и другие).

Код, который делает эту работу, довольно светлый и работает как в bash 3, так и в bash 4 (это единственные версии, с которыми я его тестировал). Если вы заинтересованы в таких трюках, которые делают разработку с bash намного приятнее и проще, вы можете взглянуть на мою Bash Infinity Framework, код ниже доступен в качестве одной из ее функций.

5 Milad P. [2016-10-24 09:49:00]

Надеюсь, этот пример поможет вам. Он берет два числа от пользователя, передает их функции add (в последней строке кода), а add будет суммировать их и распечатать.

3 Wil [2017-02-20 23:19:00]

Думаю, что я запишусь с упоминанием другого способа передать именованные параметры в bash. передавая по ссылке. Это поддерживается как bash 4.0

Альтернативный синтаксис для bash 4.3 использует nameref

Несмотря на то, что nameref намного удобнее в том, что он бесшовно разыгрывает, некоторые более старые поддерживаемые дистрибутивы по-прежнему отправляют более старую версию, t рекомендую это еще совсем.

1 Adiii [2017-11-23 16:12:00]

Простой пример, который будет очищаться как во время выполнения script, так и внутри script при вызове функции.

Ссылка на основную публикацию
Adblock detector