Я работаю со скриптом bash и хочу выполнить функцию для вывода возвращаемого значения:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Когда я выполняю fun2
, он не печатает «34». Почему это так?
bash
function
return-value
Миндиа
источник
источник
return
в вашем случае это по сути то же самое,exit code
что и диапазон от0 - 255
. Используйтеecho
как предложено @septi. Коды выхода могут быть записаны с$?
.function a() { echo 34; }
function b() { while read data; do echo $data ; done ;}
a | b
Ответы:
Несмотря на то, что bash имеет
return
оператор, единственное, что вы можете указать с его помощью, это собственныйexit
статус функции (значение между0
и255
, 0 означает «успех»). Такreturn
что не то, что вы хотите.Возможно, вы захотите преобразовать ваш
return
оператор вecho
оператор - таким образом, вывод вашей функции может быть получен с помощью$()
фигурных скобок, что кажется именно тем, что вы хотите.Вот пример:
Другой способ получить возвращаемое значение (если вы просто хотите вернуть целое число 0-255) - это
$?
.Кроме того, обратите внимание, что вы можете использовать возвращаемое значение, чтобы использовать логическую логику, которая
fun1 || fun2
будет запускаться, толькоfun2
еслиfun1
возвращает0
значение. Возвращаемым значением по умолчанию является выходное значение последнего оператора, выполненного в функции.источник
fun1
а затем возвращаемое значение сохраняется в$?
. Хотя я бы не рекомендовал это делать ...$?
?||
конструкцией, код выхода 0 считается успешным и, следовательно, "верным". Ненулевое значение является ошибкой и, следовательно, ложным. Думайтеfun1 || fun2
как сокращение для «если fun1 возвращает успех или fun2 возвращает успех», а не как оператор самих фактических возвращаемых значений.$(...)
захватывает текст, отправленный на стандартный вывод командой, содержащейся в.return
не выводит на стандартный вывод.$?
содержит код результата последней команды.источник
return
используется для настройки,$?
которая являетсяexit status
. В приведенном выше примере,fun1
«sexit status
будет34
. Также обратите внимание, что$(...)
также захватывает stderr в дополнение к stdout из указанной команды.Функции в Bash не являются функциями, как на другом языке; они на самом деле команды. Таким образом, функции используются так, как если бы они были двоичными файлами или скриптами, извлеченными из вашего пути. С точки зрения логики вашей программы не должно быть никакой разницы.
Команды оболочки связаны трубами (или потоками), а не фундаментальными или определяемыми пользователем типами данных, как в «реальных» языках программирования. Нет такой вещи, как возвращаемое значение для команды, возможно, в основном потому, что нет реального способа объявить это. Это может произойти на странице руководства или на
--help
выходе команды, но оба они доступны только для чтения человеком и, следовательно, записываются на ветер.Когда команда хочет получить ввод, она читает ее из своего потока ввода или списка аргументов. В обоих случаях текстовые строки должны быть проанализированы.
Когда команда хочет что-то вернуть, она должна
echo
передать это в свой выходной поток. Другой часто практикуемый способ - хранить возвращаемое значение в выделенных глобальных переменных. Запись в выходной поток является более четкой и гибкой, поскольку она также может принимать двоичные данные. Например, вы можете легко вернуть BLOB:Как написали другие в этом потоке, вызывающая сторона также может использовать подстановку команд
$()
для захвата вывода.Параллельно функция «вернет» код выхода
gpg
(GnuPG). Думайте о коде выхода как о бонусе, которого нет в других языках, или, в зависимости от вашего темперамента, как о «Schmutzeffekt» функциях оболочки. По условию это состояние равно 0 в случае успеха или целое число в диапазоне 1-255 для чего-то еще. Чтобы прояснить это:return
(напримерexit
) может принимать значение только от 0 до 255, а значения, отличные от 0, не обязательно являются ошибками, как это часто утверждается.Если вы не предоставите явное значение со
return
статусом, оно берется из последней команды в инструкции / функции / команды Bash и так далее. Так что всегда есть статус, иreturn
это просто простой способ его предоставления.источник
return
Оператор устанавливает код завершения функции, так же , какexit
будет делать для всего сценария.Код выхода для последней команды всегда доступен в
$?
переменной.источник
Проблема с другими ответами заключается в том, что они либо используют глобальные переменные, которые могут быть перезаписаны, когда несколько функций находятся в цепочке вызовов, либо
echo
это означает, что ваша функция не может выводить диагностическую информацию (вы забудете, что ваша функция выполняет это, и "результат", т.е. возвращает значение, будет содержать больше информации, чем ожидает ваш вызывающий объект, что приведет к странным ошибкам) илиeval
слишком тяжелым и хакерским.Правильный способ сделать это - поместить в функцию материал верхнего уровня и использовать
local
правило динамической видимости bash. Пример:Это выводы
Динамическая область видимости означает, что
ret_val
в зависимости от абонента указывается на другой объект! Это отличается от лексической области видимости, которая используется большинством языков программирования. На самом деле это документированная функция , которую легко не заметить, и она не очень хорошо объяснена, вот документация к ней (выделение мое):Для кого-то с фоном C / C ++ / Python / Java / C # / javascript это, вероятно, самое большое препятствие: функции в bash не являются функциями, они являются командами и ведут себя как таковые: они могут выводить в
stdout
/stderr
, они могут передавать в / out, они могут вернуть код выхода. По сути, нет никакой разницы между определением команды в скрипте и созданием исполняемого файла, который можно вызывать из командной строки.Так что вместо того, чтобы писать свой сценарий так:
напишите это так:
где
main()
объявляетсяret_val
какlocal
и все другие функции возвращают значения черезret_val
.См. Также следующий вопрос по Unix и Linux: Область действия локальных переменных в функциях оболочки .
Другое, возможно, даже лучшее решение, в зависимости от ситуации, - это то , которое использует ya.teck
local -n
.источник
Еще один способ добиться этого - ссылки на имена (требуется Bash 4.3+).
источник
-n <name>=<reference>
делает: делает вновь созданную переменную ссылкой на другую указанную<reference>
. Дальнейшие присвоения<name>
выполняются для указанной переменной.Мне нравится делать следующее, если выполняется в сценарии, где определена функция:
Мне нравится это, потому что я могу включить эхо-операторы в свои функции, если я хочу
источник
В качестве дополнения к отличным постам других, вот статья, обобщающая эти приемы:
Возвращение значений из функций Bash
источник
Git Bash в Windows с использованием массивов для нескольких возвращаемых значений
BASH КОД:
ОЖИДАЕМЫЙ ВЫХОД:
источник