Bash 함수에서 부울 리턴


211

파일에 특정 속성이 있는지 확인하고 true 또는 false를 반환하는 bash 함수를 작성하고 싶습니다. 그런 다음 "if"의 스크립트에서 사용할 수 있습니다. 하지만 무엇을 반환해야합니까?

function myfun(){ ... return 0; else return 1; fi;}

다음과 같이 사용합니다.

if myfun filename.txt; then ...

물론 이것은 작동하지 않습니다. 이것이 어떻게 이루어질 수 있습니까?


3
function키워드를 삭제 , myfun() {...}충분
glenn jackman

2
무엇에 중요 if의 제로 종료 상태입니다 myfun: 경우 myfun에 종료 0, then ...실행; 이 경우 어떤 다른 else ... 실행된다.
Eelvex

7
@nhed : function키워드는 bashism이며 다른 쉘에서는 구문 오류가 발생합니다. 기본적으로 불필요하거나 금지되어 있으므로 왜 사용합니까? grep 대상으로는 유용하지 않습니다 ( ()그 대신 grep ).
Gordon Davisson

3
@GordonDavisson : 무엇? 다른 껍질이 있습니까? ;-)
nhed

0과 1을 사용하지 마십시오. stackoverflow.com/a/43840545/117471
Bruno Bronosky

답변:


333

true는 0, false는 1을 사용하십시오.

견본:

#!/bin/bash

isdirectory() {
  if [ -d "$1" ]
  then
    # 0 = true
    return 0 
  else
    # 1 = false
    return 1
  fi
}


if isdirectory $1; then echo "is directory"; else echo "nopes"; fi

편집하다

@ amichair의 의견에서 이것들도 가능합니다

isdirectory() {
  if [ -d "$1" ]
  then
    true
  else
    false
  fi
}


isdirectory() {
  [ -d "$1" ]
}

4
필요하지 않습니다. 샘플을 참조하십시오.
Erik

46
가독성을 높이기 위해 'true'명령 (아무것도하지 않고 성공적으로 완료, 즉 0을 리턴 함) 및 'false'명령 (아무것도하지 않고 성공적으로 완료되지 않은, 즉 0이 아닌 값을 리턴 함)을 사용할 수 있습니다. 또한 명시적인 return 문없이 종료되는 함수는 마지막으로 실행 된 명령의 종료 코드를 반환하므로 위의 예에서 함수 본문은로만 축소 될 수 있습니다 [ -d "$1" ].
amichair

24
Bengt : "오류 코드"로 생각하면 이해가됩니다 : 오류 코드 0 = 모든 문제가 해결되었습니다 = 0 오류; 오류 코드 1 =이 호출이 수행해야 할 주요 작업은 실패했습니다. 다른 : 실패! 맨 페이지에서 찾아보십시오.
날으는 양

7
프로그래밍에서는 일반적으로 한 가지 방식 으로 만 성공할 수 있지만 무한한 방식으로 실패 할 수 있다는 점을 고려하면 의미가 있습니다 . 글쎄, 아마도 무한하지는 않지만, 많은 가능성은 우리를 상대로 쌓입니다. 성공 / 오류가 부울이 아닙니다. 나는 이것이 "참에는 0을, 거짓에는 1을 사용한다"고 생각합니다. "성공에 0을 사용하고 실패에 0이 아닌"을 읽어야합니다.
Davos

6
0과 1을 사용하지 마십시오. stackoverflow.com/a/43840545/117471
Bruno Bronosky

167

250 개 이상의 공감대가 있음에도 불구하고 내가 말하는 것을 신경 써야하는 이유

그것은 것이 아니다 0 = true1 = false. 그것은이다 제로 수단없이 실패 (성공)비 - 제로 수단 장애 (N 형의) .

그동안 선택 대답은 기술적으로 "참" 제발 넣지 마십시오 return 1에 대한 코드에서 ** 거짓 . 불행한 부작용이 몇 가지 있습니다.

  1. 숙련 된 개발자가 당신을 아마추어로 여기게됩니다 (아래 이유로).
  2. 숙련 된 개발자는이 작업을 수행하지 않습니다 (아래의 모든 이유로).
  3. 오류가 발생하기 쉽습니다.
    • 숙련 된 개발자조차도 위와 같은 이유로 0과 1을 각각 false와 true로 오인 할 수 있습니다.
  4. 그것은 외롭고 우스운 의견을 요구하거나 장려 할 것이다.
  5. 실제로 암시 적 반환 상태보다 유용하지 않습니다.

배쉬 배우기

bash는 설명서가 말한다 (강조 광산)

반환 [n]

쉘 함수가 실행을 중지하고 호출자에게 n 값을 리턴하십시오. n이 제공되지 않으면 리턴 값은 함수에서 마지막으로 실행명령종료 상태입니다 .

따라서 True와 False를 나타 내기 위해 0과 1을 사용할 필요는 없습니다. 그들이 그렇게한다는 사실은 본질적으로 코드 디버깅, 질문 인터뷰 및 초보자의 마음을 사로 잡는 데 유용한 사소한 지식입니다.

bash 매뉴얼 은 또한 말합니다

그렇지 않으면 함수의 리턴 상태는 마지막으로 실행 된 명령종료 상태입니다.

bash 매뉴얼 은 또한 말합니다

( $? ) 가장 최근에 실행 된 포 그라운드 파이프 라인종료 상태로 확장됩니다 .

우와, 기다려 관로? bash 매뉴얼을 한번 더 봅시다 .

파이프 라인은 제어 연산자 '|'중 하나로 분리 된 하나 이상의 명령 시퀀스입니다. 또는 '| &'.

예. 그들은 1 개의 명령이 파이프 라인이라고 말했다. 그러므로,이 인용문들 모두가 같은 말을하고 있습니다.

  • $? 마지막에 일어난 일을 알려줍니다.
  • 거품이 일어납니다.

내 대답

따라서 @Kambus는 이러한 간단한 기능으로 전혀 return필요 하지 않음을 보여주었습니다 . 나는 이것을 읽을 대부분의 사람들의 요구와 비교할 때 비현실적으로 단순하다고 생각합니다.

return?

함수가 마지막 명령의 종료 상태를 반환한다면 왜 return전혀 사용하지 않습니까? 함수 실행을 중지시키기 때문입니다.

여러 조건에서 실행 중지

01  function i_should(){
02      uname="$(uname -a)"
03
04      [[ "$uname" =~ Darwin ]] && return
05
06      if [[ "$uname" =~ Ubuntu ]]; then
07          release="$(lsb_release -a)"
08          [[ "$release" =~ LTS ]]
09          return
10      fi
11
12      false
13  }
14
15  function do_it(){
16      echo "Hello, old friend."
17  }
18
19  if i_should; then
20    do_it
21  fi

우리가 여기있는 것은 ...

LHS가 true 인 경우에만 04RHS &&가 실행 되므로 Line 은 명시적인 [-ish] 리턴 true 입니다.

라인 09은 라인 상태와 일치하는 true 또는 false를 반환합니다.08

13때문에 줄 이 false를 반환12

(예, 골프를 치를 수는 있지만 전체 예가 고려되었습니다.)

또 다른 일반적인 패턴

# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
    echo "some_command failed"
fi

# Do this...
some_command
status=$?
if ! $(exit $status); then
    echo "some_command failed"
fi

status변수를 설정하면 의 의미를 어떻게 알 수 있는지 확인 하십시오 $?. (물론 당신은 무슨 $?의미 인지 알지만 언젠가는 구글보다 지식이 부족한 사람이 있습니다. 코드가 고주파 거래를하지 않는 한, 사랑을 보여주고 변수를 설정하십시오.) 그러나 실제로 테이크 아웃은 "만약 존재하지 않음 "또는 반대로"종료 상태 인 경우 "를 크게 읽고 의미를 설명 할 수 있습니다. 그러나 마지막 단어 exit는 너무 야심적 일 수 있습니다. 단어 를 보면 실제로 스크립트가 종료되고 $(...)서브 쉘 이 종료 될 때 스크립트를 종료한다고 생각할 수 있습니다 .


** 당신 return 1이 거짓 을 절대적으로 사용한다고 주장한다면 , 적어도 return 255대신 사용 하는 것이 좋습니다 . 이로 인해 미래의 자기 자신이나 코드를 유지해야하는 다른 개발자가 "왜 255입니까?" 그러면 그들은 적어도주의를 기울이고 실수를 피할 수있는 더 좋은 기회를 갖게 될 것입니다.


1
거짓 및 참에 대한 @ZeroPhase 1 & 0은 말도 안됩니다. 이진 데이터 형식이 있으면 그 이유가 없습니다. bash에서 다루는 것은 성공 (단일) 및 실패 (복수)를 반영 하는 상태 코드 입니다. " if성공적으로 그렇게하세요 else." 무엇에 성공? true / false를 검사하고, 문자열, 정수, 파일, 디렉토리, 쓰기 권한, glob, regex, grep 또는 장애가 발생할 수 있는 다른 명령을 검사 할 수 있습니다 .
Bruno Bronosky

3
0/1을 반환 값으로 표준으로 사용하지 않는 것은 혼란스럽고 혼동되기 쉽다는 이유로 바보입니다. 전체 셸 언어 는 혼란스럽고 혼동되기 쉽습니다. Bash 자체는 자체 truefalse명령 에 0/1 = true / false 규칙을 사용합니다. 즉, 키워드는 true문자 그대로 0 상태 코드로 평가됩니다. 또한 if-then 문은 본질적으로 성공 코드가 아닌 부울에서 작동합니다. 부울 연산 중에 오류가 발생하면 true 또는 false를 리턴하지 않고 단순히 실행을 중단해야합니다. 그렇지 않으면 오탐 (pun)이 발생합니다.
Beejor

1
"if! $ (exit $ status);"-더 나은 설명이 필요합니다. 직관적이지 않습니다. 메시지를 인쇄하기 전에 프로그램을 종료할지 여부를 고려해야합니다. 나머지 답변은 좋았지 만 망쳤습니다.
Craig Hicks

1
@BrunoBronosky 나는 당신의 대답을 읽었으며 내용 파이프 라인 (stdin-> stdout)과 반환 값의 오류 코드의 차이점을 이해한다고 생각합니다. 그러나 사용 return 1을 피해야 하는 이유를 이해하지 못합니다 . 내가 validate기능 이 있다고 가정하면 return 1유효성 검사가 실패하는 것이 합리적 이라고 생각 합니다. 결국, 제대로 처리되지 않으면 (예 :을 사용하는 경우 set -e) 스크립트 실행을 중지해야합니다 .
JepZ

1
@Jepz 좋은 질문입니다. 올바른지 확인 return 1하십시오. 내 우려는 여기에“0 = true 1 = 거짓은 [부정 단어 삽입]”이라는 모든 의견입니다. 그 사람들은 언젠가 코드를 읽을 것입니다. 따라서 그들이 return 255(또는 42 또는 2) 보고 더 그것에 대해 생각하고 "진실"로 착각하지 않도록 도와야합니다. set -e여전히 그것을 잡을 것입니다.
Bruno Bronosky

31
myfun(){
    [ -d "$1" ]
}
if myfun "path"; then
    echo yes
fi
# or
myfun "path" && echo yes

1
부정은 어떻습니까?
einpoklum

@einpoklum은 어떻습니까?
Mark Reed

@MarkReed : "else"사례를 예제에 추가했습니다.
einpoklum

myfun "경로"|| echo no
Hrobky

13

-d 옵션으로 만 디렉토리를 검사 할 때주의하십시오!
변수 $ 1이 비어 있으면 검사는 계속 성공합니다. 변수가 비어 있지 않은지도 확인하십시오.

#! /bin/bash

is_directory(){

    if [[ -d $1 ]] && [[ -n $1 ]] ; then
        return 0
    else
        return 1
    fi

}


#Test
if is_directory $1 ; then
    echo "Directory exist"
else
    echo "Directory does not exist!" 
fi

1
이것이 어떻게 질문에 대답했는지 확실하지 않습니다. 비어있는 $ 1은 비어있을 때 true를 리턴 할 수 있지만 bash 함수에서 true 또는 false를 리턴하는 방법에 대한 통찰력을 제공하지는 않습니다. "빈 쉘 변수에 대해 테스트를 수행하면 어떻게됩니까?"라는 새로운 질문을 작성하는 것이 좋습니다. 그리고 이것을 답변으로 게시하십시오.
DRaehal

3
$1( "$1") 에 적절한 따옴표를 추가 하면 빈 변수를 확인할 필요가 없습니다. 은 [[ -d "$1" ]]이 때문에 실패 ""디렉토리가 아니다.
morgents

3

나는 내가 넘어 뜨리고있는 점 (명백하게 아직 언급되지 않았는가)을 만났다. 즉, 부울 을 리턴 하는 방법이 아니라 올바르게 평가하는 방법입니다.

나는 말하려고 if [ myfunc ]; then ...했지만 그것은 잘못입니다. 대괄호를 사용해서는 안됩니다! if myfunc; then ...그렇게하는 방법입니다.

에 따라 @Bruno 등은 반복, true하고 false있는 명령 하지 값! 쉘 스크립트에서 부울을 이해하는 것이 매우 중요합니다.

이 게시물에서 나는 설명과 부울 사용하여 시연 변수를 : https://stackoverflow.com/a/55174008/3220983 . 밀접하게 관련되어 있기 때문에 확인하는 것이 좋습니다.

다음 은 함수에서 부울을 반환하고 평가 하는 몇 가지 예를 제공 합니다.

이:

test(){ false; }                                               
if test; then echo "it is"; fi                                 

에코 출력이 없습니다. (즉, 거짓을 false 반환 )

test(){ true; }                                                
if test; then echo "it is"; fi                                 

생산 :

it is                                                        

(즉, true를 true 돌려줍니다 )

test(){ x=1; }                                                
if test; then echo "it is"; fi                                 

생산 :

it is                                                                           

0 (즉, true)이 리턴 되었기 때문에 암시 적 입니다.

자, 이것은 나를 망치고 있었던 것입니다 ...

test(){ true; }                                                
if [ test ]; then echo "it is"; fi                             

생산 :

it is                                                                           

test(){ false; }                                                
if [ test ]; then echo "it is"; fi                             

또한 다음을 생성합니다.

it is                                                                           

여기에 괄호를 사용하여 오 탐지가 발생했습니다 ! ( "외부"명령 결과는 0이라고 추측합니다.)

내 게시물에서 가장 중요한 것은 다음과 같습니다. 괄호를 사용하여 일반적인 평등 검사와 같은 부울 함수 (또는 변수)를 평가하지 마십시오 if [ x -eq 1 ]; then....


2

사용 true또는 false즉시 전에 명령을 return다음 return매개 변수없이. 는 return마지막 명령의 값을 자동으로 사용합니다.

인수를 제공하는 return것은 일관성이없고, 유형에 따라 다르며 1 또는 0을 사용하지 않는 경우 오류가 발생하기 쉽습니다. 이전 의견에서 언급했듯이 1 또는 0을 사용하는 것이이 함수에 접근하는 올바른 방법이 아닙니다.

#!/bin/bash

function test_for_cat {
    if [ $1 = "cat" ];
    then
        true
        return
    else
        false
        return
    fi
}

for i in cat hat;
do
    echo "${i}:"
    if test_for_cat "${i}";
    then
        echo "- True"
    else
        echo "- False"
    fi
done

산출:

$ bash bash_return.sh

cat:
- True
hat:
- False

1

이것을 this function myfun(){ ... return 0; else return 1; fi;}로 다시 작성하면 작동 할 수 있습니다 function myfun(){ ... return; else false; fi;}. 그것은 false함수의 마지막 명령어라면 전체 함수에 대해 잘못된 결과를 얻지 만 return어쨌든 진정한 결과로 함수를 중단합니다. 내 배쉬 인터프리터에게는 적어도 사실이라고 생각합니다.


1

함수 출력을 테스트하는 가장 짧은 형식은 단순히

do_something() {
    [[ -e $1 ]] # e.g. test file exists
}

do_something "myfile.txt" || { echo "File doesn't exist!"; exit 1; }

1

코드 가독성을 위해 true / false를 반환해야한다고 생각합니다.

  • 한 줄에있다
  • 하나의 명령이다
  • 기억하기 쉽다
  • 키워드 return다음에 다른 키워드를 언급하십시오 ( true또는 false)

내 솔루션은 return $(true)또는 return $(false)으로 표시된 :

is_directory()
{
    if [ -d "${1}" ]; then
        return $(true)
    else
        return $(false)
    fi
}

0

@Bruno Bronosky 및 @mrteatime에 이어 부울 리턴을 "뒤로"작성하라는 제안을 제공합니다. 이것이 내가 의미하는 바입니다.

foo()
{
    if [ "$1" == "bar" ]; then
        true; return
    else
        false; return
    fi;
}

따라서 모든 return 문에 대한 추악한 두 줄 요구 사항이 제거됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.