아래에 선언 된 호출 함수


15

bash에서 아래에 선언 된 함수를 호출 할 수 있습니까?

if [ "$input" = "yes" ]; then
    YES_FUNCTION
elif [ "$input" = "no" ]; then
    NO_FUNCTION
else
    exit 0;
fi

YES_FUNCTION()
{
  .....
  .....
}

NO_FUNCTION()
{
  .....
  .....
}

답변:


36

다른 사람들이 말했듯이 그렇게 할 수 없습니다.

그러나 주 프로그램이 파일의 맨 위에 있고 다른 함수가 아래에 정의되도록 코드를 하나의 파일로 정렬하려면 별도의 main함수 를 사용하여 수행 할 수 있습니다 .

예 :

#!/bin/sh

main() {
    if [ "$1" = yes ]; then
        do_task_this
    else
        do_task_that
    fi
}

do_task_this() {
    ...
} 
do_task_that() {
    ...
} 

main "$@"; exit

main파일 끝에서 호출하면 모든 함수가 이미 정의되어 있습니다. 스크립트에서 명령 행 인수를 함수에 표시하려면 명시 적으로 전달 "$@"해야 main합니다.

exitmain에 대한 호출과 동일한 행에있는 명시 적은 필수는 아니지만 스크립트 파일이 수정 된 경우 실행중인 스크립트가 엉망이되는 것을 방지하는 데 사용할 수 있습니다. 그것이 없으면, 쉘은 main리턴 후에 스크립트 파일에서 명령을 계속 읽으려고 시도 합니다. ( 전체 셸 스크립트를 실행하기 전에 읽는 방법을 참조하십시오 . )


@ikkachu 작동해야한다고 생각합니다. 확인하겠습니다.
msp9011

7
Bash 스크립트를 사용 [[ ${BASH_SOURCE[0]} = "$0" ]] && Main "$@"하면 주 함수를 호출하는 데 자주 사용 되므로 Main실행 하지 않고 다른 스크립트에서 소스를 사용할 수 있습니다 . 그런 다음 함수를 재사용하거나 테스트를 작성하여 확인할 수 있습니다.
BlackJack

11
main "$@"; exit(와 exit같은 라인과 (와) 같은 것은 main그것을 해석하는 동안 파일에 대한 보호가 수정되는대로)도 유용하다.
Stéphane Chazelas 2016 년

2
@JoL, 읽은 내용은 다시 읽지 않으며 셸은 루프를 시작하기 전에 루프의 전체 텍스트를 읽고 구문 분석해야하지만 루프가 반환되면 나머지 파일에서 읽습니다. 현재 위치 (그리고 파일이 수정되면 문제를 일으킬 것입니다). 모든 것이 함수 안에 있다면 , 쉘이 리턴 후에 파일에서 아무것도 읽지 않도록하는 exit것과 같은 행에 놓으면, 그 함수를 정의하는 것을 제외하고, 무엇이든하기 시작하기 전에 모든 것을 main읽어야 main합니다.
Stéphane Chazelas 2016 년

1
@MontyHarder는, 당신이 사용하는 경우 중요하지 않습니다 main; exit, main; exit $?또는 main <EOF>모든 경우의 종료 코드 main스크립트의 종료 코드로 사용됩니다. 는 exit누군가가 실행 중에 스크립트를 편집 할 경우 단지 엉망지고 일을 방지하는 것입니다.
ilkkachu

13

아니오, 함수는 호출 할 때 쉘 환경에 존재해야합니다.

Google의 "쉘 스타일 가이드" 에 다음과 같은 수정 사항이 있습니다.

main하나 이상의 다른 함수를 포함 할 수있을 정도로 긴 스크립트에는 호출 된 함수 가 필요합니다.

스크립트의 맨 마지막에는 모든 함수 다음에 함수에없는 유일한 명령문으로서

main "$@"

이것은 main스크립트에 주어진 매개 변수로 함수를 호출합니다 . 이 main기능은 스크립트 상단에 위치 할 수 있습니다 (스타일 가이드는 하단에 배치한다고 말하지만 다시 많은 것을 말합니다).

셸이 main호출되면 스크립트의 모든 함수가 구문 분석되어 main함수 내에서 호출 될 수 있습니다 .


9

아니요, 함수는 사용하기 전에 선언해야합니다. 쉘 스크립트는 한 줄씩 읽히고 한 줄씩 실행됩니다. 따라서 선언이 실행될 때까지 함수가 존재하지 않습니다.


네 말이 맞아 문제는 스크립트에 30 개 이상의 기능이 있다는 것입니다. 코드를 읽을 때 꽤 까다 롭습니다. 에서 C이 편안합니다.
msp9011

3
함수 선언을 다른 파일에 넣고 소싱 할 수 있습니다 ( . yourfile).
Stephen Kitt

예, 시도했지만 하나의 스크립트가 필요합니다.
msp9011

@SivaPrasath 정확히 무엇이 문제입니까? 모든 함수를 정의하고 아마도 메인 코드를 함수에 넣은 다음 마지막 줄은 어떤 함수가 호출되고 스크립트의 주요 부분을 포함하는지 보여줍니다.
BlackJack

@SivaPrasath C에서는 if함수 외부에 간단한 설명 이 없습니다 . 이 기능은 당신이 때 정의 할 필요가 없습니다 선언if 당신이 바로 그 때, 함유 함수를 호출 을.
chepner

4

쉘에는 declaring기능 개념이 없습니다 . 따라서 앞으로 선언 할 수 없습니다.

결과적으로, 호출하기 전에 쉘이 함수 구현을 읽도록해야합니다.


4
기술적으로 일부 쉘 (ksh, zsh)에는 어떤 형태의 선언 으로 볼 수 있는 함수 자동로드 기능이 있습니다 (여기서 함수를 선언하지만 본문은 첫 번째 호출시 에만 로드 됨 ). 그러나 OP에는 적용되지 않습니다 . autoload fbash
Stéphane Chazelas 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.