Bash 함수의 반환 값
bash 스크립트로 작업 중이며 반환 값을 인쇄하는 함수를 실행하고 싶습니다.
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
를 실행하면 fun2
"34"가 인쇄되지 않습니다. 왜 이런 경우입니까?
bash는 return
문장을 가지고 있지만 , 이것으로 지정할 수있는 유일한 것은 함수의 자체 exit
상태 ( 0
과 255
성공 사이의 0 과 0 사이의 값 )입니다. 그래서 return
당신이 원하는 것이 아닙니다.
return
명령문을 명령문 으로 변환하고 싶을 수도 있습니다. 이렇게하면 echo
함수 출력을 $()
중괄호를 사용하여 캡처 할 수 있습니다 .
예를 들면 다음과 같습니다.
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으로 전송 된 텍스트를 캡처합니다. return
stdout으로 출력하지 않습니다. $?
마지막 명령의 결과 코드를 포함합니다.
fun1 (){
return 34
}
fun2 (){
fun1
local res=$?
echo $res
}
Bash의 함수는 다른 언어와 같은 함수가 아닙니다. 그들은 실제로 명령입니다. 따라서 함수는 마치 경로에서 가져온 바이너리 또는 스크립트 인 것처럼 사용됩니다. 프로그램 로직의 관점에서 보면 아무런 차이가 없어야합니다.
쉘 명령은 "실제"프로그래밍 언어에서와 같이 기본 또는 사용자 정의 데이터 유형이 아닌 파이프 (일명 스트림)로 연결됩니다. 명령의 반환 값과 같은 것은 없습니다. 주로 그것을 선언하는 실제 방법이 없기 때문일 수 있습니다. 맨 페이지 또는 --help
명령 의 출력에서 발생할 수 있지만 둘 다 사람이 읽을 수 있으므로 바람에 기록됩니다.
명령이 입력을 받으려면 입력 스트림 또는 인수 목록에서 명령을 읽습니다. 두 경우 모두 텍스트 문자열을 구문 분석해야합니다.
명령이 무언가를 반환하려고 할 때 echo
출력 스트림에 있어야합니다. 자주 실행되는 또 다른 방법은 반환 값을 전용 전역 변수에 저장하는 것입니다. 출력 스트림에 쓰는 것은 바이너리 데이터도 필요로하기 때문에보다 명확하고 유연합니다. 예를 들어, BLOB을 쉽게 리턴 할 수 있습니다.
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
다른 사람들이이 스레드에서 작성했듯이 호출자는 명령 대체 $()
를 사용 하여 출력을 캡처 할 수도 있습니다 .
병렬로, 함수는 gpg
(GnuPG) 의 종료 코드를 "반환"합니다 . 종료 코드를 다른 언어에없는 보너스 또는 기질에 따라 쉘 기능의 "Schmutzeffekt"로 생각하십시오. 이 상태는 일반적으로 성공시 0 또는 1-255 범위의 정수입니다. 이를 명확하게하기 위해 return
(와 같은 exit
)는 0-255의 값만 취할 수 있으며 0 이외의 값은 종종 주장되는 것처럼 반드시 오류는 아닙니다.
명시적인 값을 제공하지 않으면 return
Bash 문 / 함수 / 명령 등의 마지막 명령에서 상태를 가져옵니다. 따라서 항상 상태 return
가 있으며이를 제공하는 쉬운 방법 일뿐입니다.
이 return
명령문은 함수의 종료 코드를 설정 exit
하며 전체 스크립트에 대해 수행 하는 것과 거의 동일 합니다.
마지막 명령의 종료 코드는 항상 $?
변수 에서 사용 가능 합니다.
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $? # <-- Always echos 0 since the 'local' command passes.
res=$(fun1)
echo $? #<-- Outputs 34
}
다른 답변의 문제는 전역을 사용 echo
한다는 것입니다.이 함수는 호출 체인에 여러 함수가있을 때 덮어 쓸 수 있거나 함수가 진단 정보를 출력 할 수 없음을 의미합니다 (함수는이 기능을 수행하지 않고 "결과"를 반환합니다. 가치, 발신자가 기대하는 것보다 많은 정보를 포함하여 이상한 버그로 이어짐) 또는 eval
너무 무겁고 해키입니다.
이를 수행하는 올바른 방법은 최상위 레벨 항목을 함수에 넣고 local
with bash의 동적 범위 지정 규칙을 사용하는 것 입니다. 예:
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
은 발신자에 따라 다른 객체 를 가리키는 것을 의미 합니다! 이것은 대부분의 프로그래밍 언어가 사용하는 어휘 범위와 다릅니다. 이것은 실제로 문서화 된 기능 이며 놓치기 쉽고 잘 설명되어 있지 않습니다. 여기에 대한 문서가 있습니다 (강조는 내 것입니다).
함수에 로컬 인 변수는 로컬 내장으로 선언 될 수 있습니다. 이러한 변수는 함수 와 호출하는 명령 에만 표시됩니다 .
는 C / C ++ / 파이썬 / 자바 / C #을 / 자바 스크립트 배경을 가진 사람의 경우, 이것은 가장 큰 장애물은 아마도 : bash는 함수는 명령하고, 같은 행동, 기능하지 않은 : 그들은 출력 할 수 stdout
/ stderr
, 그들은 파이프에서와 수 / out, 종료 코드를 반환 할 수 있습니다. 기본적으로 스크립트에서 명령을 정의하는 것과 명령 줄에서 호출 할 수있는 실행 파일을 만드는 것에는 차이가 없습니다.
따라서 다음과 같이 스크립트를 작성하는 대신
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
여기서 as를 main()
선언 하고 다른 모든 함수 는 ret_val
을 local
통해 값을 반환합니다 ret_val
.
다음 유닉스 및 리눅스 질문 : 셸 함수의 로컬 변수 범위를 참조하십시오 .
상황에 따라 더 나은 솔루션 중 하나 는 ya.teck 이 게시 한 솔루션 입니다 local -n
.
이를 달성하는 또 다른 방법은 이름 참조입니다 (Bash 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"
}
다른 사람의 훌륭한 게시물에 대한 추가 기능으로 다음은 이러한 기술을 요약 한 기사입니다.
- 전역 변수를 설정
- 함수에 이름을 전달한 전역 변수를 설정하십시오.
- 리턴 코드를 설정하고 $?
- 일부 데이터를 '반향'(MYVAR = $ (myfunction)으로 선택)
여러 반환 값에 배열을 사용 하는 Windows의 Git 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:
참고 URL : https://stackoverflow.com/questions/17336915/return-value-in-a-bash-function
'Programing' 카테고리의 다른 글
필요한 'using'문을 자동으로 추가하는 Visual Studio 키보드 단축키 (0) | 2020.04.04 |
---|---|
HttpContent.ReadAsAsync는 어디에 있습니까? (0) | 2020.04.04 |
tensorflow에서 이름 범위와 변수 범위의 차이점은 무엇입니까? (0) | 2020.04.04 |
Java에서 변수 인수가있는 메소드에 배열을 인수로 전달할 수 있습니까? (0) | 2020.04.04 |
.NET EXE를 읽을 수있는 C # 소스 코드로 어떻게 디 컴파일합니까? (0) | 2020.04.04 |