it-gundan.com

"function foo () {}"와 "foo () {}"의 차이점

bash 키워드를 사용하거나 생략하여 function 함수를 정의 할 수 있습니다. 차이점이 있습니까?

#!/bin/bash

function foo() {
  echo "foo"
}

bar() {
  echo "bar"
}

foo

bar

함수 foobar에 대한 두 호출이 모두 성공하고 차이가 없습니다. 그래서 가독성을 향상시키는 것입니까, 아니면 내가 놓친 것이 있는지 궁금합니다 ...

dash (/bin/sh는 debian/ubuntu의 dash에 링크되어 있습니다.) function 키워드를 사용할 때 실패합니다.

103
Carlos Campderrós

두 번째 버전이 더 이식 가능하다는 점 외에는 AFAIK의 차이점이 없습니다.

44
schaiba

function 키워드는 ksh 에 도입되었습니다. 전통적인 Bourne Shell 에는 foo () 구문 만 있고 POSIX foo () 만 표준화합니다. 통사론.

ATT ksh (pdksh는 아님)에서 function로 정의 된 함수와 Bourne/POSIX 구문으로 정의 된 함수 사이에는 약간의 차이가 있습니다. function로 정의 된 함수에서 typeset 키워드는 지역 변수를 선언합니다. 함수가 종료되면 변수 값이 함수에 들어가기 전의 값으로 재설정됩니다. 고전적인 구문에서 변수는 typeset 사용 여부에 관계없이 전역 범위를 갖습니다.

$ ksh -c 'a=global; f () { typeset a=local; }; f; echo $a'
local
$ ksh -c 'a=global; function f { typeset a=local; }; f; echo $a'
global

Ksh의 또 다른 차이점은 function 키워드로 정의 된 함수에는 자체 트랩 컨텍스트가 있다는 것입니다. 함수 외부에서 정의 된 트랩은 함수를 실행하는 동안 무시되며 함수 내부의 치명적인 오류는 전체 스크립트가 아닌 함수 만 종료합니다. 또한 $0function로 정의 된 함수의 함수 이름이지만 ()로 정의 된 함수의 스크립트 이름입니다.

Pdksh는 ATT ksh를 에뮬레이션하지 않습니다. pdksh에서 typeset는 함수에 관계없이 로컬 범위 변수를 생성하며 로컬 트랩은 없습니다 (function를 사용하면 약간의 차이가 있지만 자세한 내용은 매뉴얼 페이지 참조).

Bash와 zsh는 ksh와의 호환성을 위해 function 키워드를 도입했습니다. 그러나이 셸에서 function foo { … }foo () { … }는 bash 및 zsh 확장명 function foo () { … }과 완전히 동일합니다. typeset 키워드는 항상 로컬 변수를 선언하고 (물론 -g 제외) 트랩은 로컬이 아닙니다 (local_traps 옵션을 설정하여 zsh에서 로컬 트랩을 얻을 수 있음).

foo() any-command

bourne과 유사한 쉘에서 지원되는 Bourne 구문이지만 bash, yash 및 최신 버전의 posh (복합 명령 만 지원). ksh의 Bourne Shell 및 AT & T 구현은 any-command가 복합 명령이 아닌 한 foo() any-command > redirections을 지원하지 않습니다.

foo() any-compound-command

(복합 명령의 예 : { cmd; }, for i do echo "$i"; done, (cmd) ... 가장 일반적으로 사용되는 { ...; })

bourne과 같은 Shell에서 지원하는 POSIX 구문과 일반적으로 사용하려는 구문입니다.

function foo { ...; }

bourn 구문보다 오래된 Korn Shell 구문입니다. Korn Shell의 AT & T 구현을 위해 특별히 작성하고 여기에서받는 특정 처리가 필요한 경우에만이 기능을 사용하십시오. 이 구문은 POSIX가 아니지만 bash, yashzsh에서 해당 쉘 (및 pdksh 기반의 Korn Shell과의 호환성을 위해 지원됨) Korn Shell의 변형은 표준 구문과 다르게 취급하지 않습니다.

function foo () { ...; }

no Shell 및 사용해서는 안 됨 의 구문입니다. Korn Shell의 bash, yash, zshpdksh 기반 변형에 의해 우연히 지원됩니다. 또한 awk 함수 구문이기도합니다.

난해한 목록을 계속 진행하면

function foo() other-compound-command

(function foo() (subshell) 또는 function foo() for i do; ... done)과 같이 더 나쁩니다. bash, yashzsh에서 지원하지만 k_, 심지어 pdksh 기반 변형도 지원하지 않습니다.

동안:

function foo() simple command

zsh에서만 지원됩니다.

35
Stéphane Chazelas

의미 상,이 두 형식은 Bash와 동일합니다.

매뉴얼 페이지에서 :

쉘 함수는 다음과 같이 선언됩니다.

name () compound-command [redirection]
function name [()] compound-command [redirection]

name라는 함수를 정의합니다. 예약어 function는 선택 사항입니다. function 예약어가 제공되면 괄호는 선택 사항입니다.

편집 : 방금이 질문에 posix 태그가 붙어 있음을 알았습니다. POSIX sh에서 function 키워드는 사용되지 않습니다 (예약되어 있지만).

22
depquid

지금까지 여러 사람들이 올바르게 대답했지만 다음은 간결한 개요입니다.

두 번째 버전은 이식 가능하며 많은 표준 (특히 POSIX) 셸에서 작동 할 수 있습니다.

첫 번째 버전은 bash에서만 작동하지만 함수 이름 뒤에 괄호를 생략 할 수 있습니다.

그렇지 않으면 bash가 해석 한 후에 동일한 엔티티를 나타냅니다.

3
destenson