Я работаю на bash-скрипт, и я хочу, чтобы выполнить функцию, чтобы напечатать возвращаемое значение:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Когда я выполнить fun2
, он не печатает на "34" по. Почему это произошло?
Хотя Баш имеет инструкция 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` значение. Возвращаемое значение по умолчанию-значение выхода выполняется последний оператор в функции.
$(...)
захватывает текст в stdout команды, содержащиеся в. "возвращение" не выводит в stdout. $?
содержит код результата выполнения последней команды.
fun1 (){
return 34
}
fun2 (){
fun1
local res=$?
echo $res
}
Функции в 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'т предоставить явное значение "возврат" статус берется из последней команды в заявлении функция команды Баш//и так далее. Так что всегда есть статус, и "возвращение" - это простой способ обеспечить это.
"Возврат" заявление устанавливает код выхода из функции, так же, как и "выход" сделает за весь сценарий.
Код выхода последней команды всегда доступны в $?
переменной.
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $? # <-- Always echos 0 since the 'local' command passes.
res=$(fun1)
echo $? #<-- Outputs 34
}
Проблему с других ответов они либо использовать глобальные, которые могут быть перезаписаны при нескольких функций в цепочке вызовов, или эхо
, что означает ваша функция не может выводить диагностическую информацию (вы забудете свои функции, это и "результат" Ну, т. е. возвращаемое значение будет содержать больше сведений, чем ваш собеседник ожидает, что приводит к странной ошибке), или функции "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 оболочка.
Другой, возможно, даже лучшее решение в зависимости от ситуации, является одним написал Я.тек, который использует локальный -Н.
Другой способ достигнуть этого имя ссылки (требует Баш 4.3+).
function example {
local -n VAR=$1
VAR=foo
}
example RESULT
echo $RESULT
Я хотел сделать следующее, если работающее в сценарий, где функция определяется:
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 "<- my_function. $POINTER"
}
В качестве дополнения к другим' отличные посты, здесь'ы статьи обобщение этих методов:
ГИТ баш на окна использование массивов для несколько возвращаемые значения
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 ##<--Call function
a=${RET_ARR[0]} && echo "RET_ARR[0]: $a "
b=${RET_ARR[1]} && echo "RET_ARR[1]: $b "
echo
##----------------------------------------------##
c="2"
d="3"
FN_MULTIPLE_RETURN_VALUES $c $d ##<--Call function
c_res=${RET_ARR[2]} && echo "RET_ARR[2]: $c_res "
d_res=${RET_ARR[3]} && echo "RET_ARR[3]: $d_res "
echo
##----------------------------------------------##
FN_MULTIPLE_RETURN_VALUES 4 5 ##<---Call function
e=${RET_ARR[4]} && echo "RET_ARR[4]: $e "
f=${RET_ARR[5]} && echo "RET_ARR[5]: $f "
echo
##----------------------------------------------##
read -p "Press Enter To Exit:"
ОЖИДАЕМЫЙ РЕЗУЛЬТАТ:
FN_MULTIPLE_RETURN_VALUES EXAMPLES:
-------------------------------------------
running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[0]: Hello
RET_ARR[1]: World
running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[2]: Hello
RET_ARR[3]: World
running: FN_MULTIPLE_RETURN_VALUES
RET_ARR[4]: Hello
RET_ARR[5]: World
Press Enter To Exit: