Возвращаемое значение в функцию bash

Я работаю на bash-скрипт, и я хочу, чтобы выполнить функцию, чтобы напечатать возвращаемое значение:

function fun1(){
  return 34
}
function fun2(){
  local res=$(fun1)
  echo $res
}

Когда я выполнить fun2, он не печатает на "34" по. Почему это произошло?

Комментарии к вопросу (3)
Решение

Хотя Баш имеет инструкция return, единственное, что можно указать С это функция's собственное "выход" статус (значение между 0 и 255, 0 означает, что "успеха"). Так что "возвращение" - это не то, что вы хотите.

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

Вот пример:

function fun1(){
  echo 34
}

function fun2(){
  local res=$(fun1)
  echo $res
}

Другой способ, чтобы получить возвращаемое значение (если вы просто хотите вернуть целое число 0-255) является $?.

function fun1(){
  return 34
}

function fun2(){
  fun1
  local res=$?
  echo $res
}

Также обратите внимание, что вы можете использовать возвращаемое значение, чтобы использовать булеву логику как из fun1 || fun2толькоfun2еслииз fun1возвращает0` значение. Возвращаемое значение по умолчанию-значение выхода выполняется последний оператор в функции.

Комментарии (12)

$(...) захватывает текст в stdout команды, содержащиеся в. "возвращение" не выводит в stdout. $? содержит код результата выполнения последней команды.

fun1 (){
  return 34
}

fun2 (){
  fun1
  local res=$?
  echo $res
}
Комментарии (2)

Функции в bash не функции, как в другом языке; они'вновь вообще-то команды. Поэтому функции используются так, как если бы они были бинарники и скрипты извлечена из вашего пути. С точки зрения вашей логике программа должна быть действительно никакой разницы.

Команды оболочки соединены трубами (потоки ака), а не фундаментальные или пользовательские типы данных, как в "Реал" и языки программирования. Нет такого понятия, как возвращаемое значение для команды, может быть, в основном потому, что там's не реальный способ заявить об этом. Это может произойти на man-странице, или параметры--Help вывод команды, но как только для человеческого восприятия и, следовательно, пишутся на ветер.

Если команда хочет получить вход, он читает ее из своего входного потока, или список аргументов. В обоих случаях текст должен быть проанализирован.

Если команда хочет вернуть что-то на " Эхо " ее в выходной поток. Еще часто практикуется способ-сохранить возвращаемое значение в выделенном, глобальные переменные. Записи в поток вывода является четкое и более гибкое, поскольку она может иметь также двоичные данные. Например, вы можете легко вернуть клякса:

encrypt() {
    gpg -c -o- $1 # encrypt data in filename to stdout (asks for a passphrase)
}

encrypt public.dat > private.dat # write function result to file

Как уже писали в этой теме, абонент также может использовать подстановку команд вместо $() Для получения вывода.

Параллельно, функция будет на "Возвращение" и код выхода Гоб (открытых). Думаю, код выхода, в качестве бонуса, что другие языки не'т иметь, или, в зависимости от вашего темперамента, как "по Schmutzeffekt" из функции Shell. Этот статус, по Конвенции, 0 в случае успеха или целое число в диапазоне 1-255 для чего-то другого. Чтобы пояснить это: "возвращение" (как и "выход") может принимать только значения от 0 до 255, а значения, отличные от 0, не обязательно ошибки, как это часто утверждается.

Когда вы Don'т предоставить явное значение "возврат" статус берется из последней команды в заявлении функция команды Баш//и так далее. Так что всегда есть статус, и "возвращение" - это простой способ обеспечить это.

Комментарии (2)

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

Код выхода последней команды всегда доступны в $? переменной.


function fun1(){
  return 34
}

function fun2(){
  local res=$(fun1)
  echo $? # 
Комментарии (0)

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

Правильный способ сделать это, чтобы положить верхний уровень в функцию и использовать "местные" с Баш'динамическое правило с обзорного. Пример:

func1() 
{
    ret_val=hi
}

func2()
{
    ret_val=bye
}

func3()
{
    local ret_val=nothing
    echo $ret_val
    func1
    echo $ret_val
    func2
    echo $ret_val
}

func3

Это выходы

nothing
hi
bye

Динамическое аналитическое исследование означает, что ret_val указывает на другой объект в зависимости от звонящего! Это отличается от лексической области видимости, который является то, что большинство языков программирования используют. Это на самом деле документированные функции, просто легко не заметить, и не очень хорошо объяснил, Вот документация на него (выделено мной):

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

Для кого-то с С/С++/питон/Ява/с#/JavaScript в фоновом режиме, это, наверное, самое большое препятствие: функции в bash не являются функциями, они являются командами, и ведут себя как таковые: они могут выводить на стандартный вывод/стандартный вывод, они могут трубы вход/выход, они могут возвращать код завершения. В принципе нет никакой разницы между определением команды в скрипт и создать исполняемый файл, который может быть вызван из командной строки.

Поэтому вместо того, чтобы писать свой скрипт вроде этого:

top-level code 
bunch of functions
more top-level code

написать это так:

# define your main, containing all top-level code
main() 
bunch of functions
# call main
main  

где основной()заявляетret_valкакместныеи все остальные функции возвращают значения черезret_val`.

См. также следующие &амп в Unix; вопрос в Linux: видимости локальных переменных в Functions оболочка.

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

Комментарии (0)

Другой способ достигнуть этого имя ссылки (требует Баш 4.3+).

function example {
  local -n VAR=$1
  VAR=foo
}

example RESULT
echo $RESULT
Комментарии (1)

Я хотел сделать следующее, если работающее в сценарий, где функция определяется:

POINTER= # used for function return values

my_function() {
    # do stuff
    POINTER="my_function_return"
}

my_other_function() {
    # do stuff
    POINTER="my_other_function_return"
}

my_function
RESULT="$POINTER"

my_other_function
RESULT="$POINTER"

Мне нравится это, потому тогда я могу включить Echo в мои функции, если я хочу


my_function() {
    echo "-> my_function()"
    # do stuff
    POINTER="my_function_return"
    echo "
Комментарии (0)

В качестве дополнения к другим' отличные посты, здесь'ы статьи обобщение этих методов:

  • устанавливает глобальную переменную
  • устанавливает глобальную переменную, имя которого передается в функцию
  • установить код возврата (и забрать его с $?)
  • 'Эхо' некоторые данные (и забрать его с аргумент myVar=$(myfunction в консоли) )

Возврат значений из функции в bash

Комментарии (0)

ГИТ баш на окна использование массивов для несколько возвращаемые значения

BASH КОД:


#!/bin/bash

##A 6-element array used for returning
##values from functions:
declare -a RET_ARR
RET_ARR[0]="A"
RET_ARR[1]="B"
RET_ARR[2]="C"
RET_ARR[3]="D"
RET_ARR[4]="E"
RET_ARR[5]="F"

function FN_MULTIPLE_RETURN_VALUES(){

   ##give the positional arguments/inputs
   ##$1 and $2 some sensible names:
   local out_dex_1="$1" ##output index
   local out_dex_2="$2" ##output index

   ##Echo for debugging:
   echo "running: FN_MULTIPLE_RETURN_VALUES"

   ##Here: Calculate output values:
   local op_var_1="Hello"
   local op_var_2="World"

   ##set the return values:
   RET_ARR[ $out_dex_1 ]=$op_var_1
   RET_ARR[ $out_dex_2 ]=$op_var_2
}

echo "FN_MULTIPLE_RETURN_VALUES EXAMPLES:"
echo "-------------------------------------------"
fn="FN_MULTIPLE_RETURN_VALUES"
out_dex_a=0
out_dex_b=1
eval $fn $out_dex_a $out_dex_b  ##
Комментарии (0)