다른 쉘 스크립트에서 쉘 스크립트의 함수를 호출 할 수 있습니까?


87

2 개의 셸 스크립트가 있습니다.

두 번째 셸 스크립트에는 second.sh 함수가 포함되어 있습니다.

func1 
func2

first.sh는 일부 매개 변수를 사용하여 두 번째 셸 스크립트를 호출하고 해당 함수에 특정한 다른 매개 변수와 함께 func1 및 func2를 호출합니다.

다음은 제가 말하는 것의 예입니다.

second.sh

val1=`echo $1`
val2=`echo $2`

function func1 {

fun=`echo $1`
book=`echo $2`

}

function func2 {

fun2=`echo $1`
book2=`echo $2`


}

first.sh

second.sh cricket football

func1 love horror
func2 ball mystery

어떻게 할 수 있습니까?



3
v=$(echo $1)완전히 중복됩니다. 그냥 쓰십시오 fun2=$1. 유일한 차이점은 $()(또는 백틱)이 후행 줄 바꿈을 제거 한다는 것입니다.
William Pursell

1
명령 줄과 달리 쉘 스크립트에서 함수를 호출하는 데 특별한 것이 없기 때문에이 질문은 "어떻게 bash 함수를 호출 하는가?"로 축소 할 수 있습니다.
톰 러셀

답변:


146

다음 second.sh과 같이 스크립트를 리팩터링하십시오 .

function func1 {
   fun=$1
   book=$2
   printf "fun=%s,book=%s\n" "${fun}" "${book}"
}

function func2 {
   fun2=$1
   book2=$2
   printf "fun2=%s,book2=%s\n" "${fun2}" "${book2}"
}

그리고 다음 first.sh과 같이 스크립트에서 이러한 함수를 호출 합니다.

source ./second.sh
func1 love horror
func2 ball mystery

산출:

fun=love,book=horror
fun2=ball,book2=mystery

12
의도하지 않은 부작용을 방지하려면 source명령이 실제로 인수로 전달 된 스크립트를 실행 한다는 점에 유의하십시오 .
dvlcube

44

다른 쉘 스크립트에서 직접 함수를 호출 할 수 없습니다.

함수 정의를 별도의 파일로 이동 한 다음 다음 .과 같이 명령을 사용하여 스크립트로로드 할 수 있습니다 .

. /path/to/functions.sh

functions.sh시점에서 콘텐츠가 실제로 파일에있는 것처럼 해석 됩니다. 이것은 쉘 함수의 공유 라이브러리를 구현하기위한 일반적인 메커니즘입니다.


3
.대한 별칭 이기 때문에 수락 된 답변과 동일하지 source않습니까?
ajsharma

10
글쎄, 내가 먼저 대답 했으므로 기술적으로 허용되는 대답은 이것과 동일합니다 :). 또한 while source.많은 셸에서 별칭 이지만 항상 그런 것은 아닙니다. 예를 들어 dash를 제공하는 Debian 의 패키지 /bin/sh에는 source명령 이 없습니다 .
larsks

source명령이 Ubuntu @ajsharma에서 작동하지 않았습니다. 참조 : sh 셸에서 소스 명령을 찾을 수 없음
rajeshmag

이 댓글이 최고로 찬성되지 않은 것이 이상합니까? 이것은 올바른 #! / bin / sh 구문이며 다른 하나는 bash에서만 작동합니다.
xddq

21

문제

현재 받아 들여지는 대답은 중요한 조건에서만 작동합니다. 주어진...

/foo/bar/first.sh:

function func1 {  
   echo "Hello $1"
}

/foo/bar/second.sh:

#!/bin/bash

source ./first.sh
func1 World

이것은이 first.sh있는 동일한 디렉토리 내 에서이 실행되는 경우에만 작동합니다 first.sh. 즉. 쉘의 현재 작업 경로가 /foo인 경우 명령 실행 시도

cd /foo
./bar/second.sh

오류를 인쇄합니다.

/foo/bar/second.sh: line 4: func1: command not found

이는 source ./first.sh스크립트의 경로가 아니라 현재 작업 경로에 상대적 이기 때문 입니다. 따라서 한 가지 해결책은 서브 쉘을 활용하고

(cd /foo/bar; ./second.sh)

보다 일반적인 솔루션

주어진...

/foo/bar/first.sh:

function func1 {  
   echo "Hello $1"
}

/foo/bar/second.sh:

#!/bin/bash

source $(dirname "$0")/first.sh

func1 World

그때

cd /foo
./bar/second.sh

인쇄물

Hello World

작동 원리

  • $0 실행 된 스크립트의 상대 또는 절대 경로를 반환합니다.
  • dirname $ 0 스크립트가있는 디렉토리의 상대 경로를 반환합니다.
  • $( dirname "$0" )dirname "$0"명령은 다음에 대한 인수로 사용되는 실행 스크립트의 디렉토리에 상대 경로를 반환 source명령
  • "second.sh"에서 /first.sh가져온 쉘 스크립트의 이름 만 추가합니다.
  • source 지정된 파일의 내용을 현재 쉘로로드합니다.

0

정의하는 경우

    #!/bin/bash
        fun1(){
          echo "Fun1 from file1 $1"
        }
fun1 Hello
. file2 
fun1 Hello
exit 0

file1 (chmod 750 file1) 및 file2

   fun1(){
      echo "Fun1 from file2 $1"
    }
    fun2(){
      echo "Fun1 from file1 $1"
    }

./file2를 실행하면 file1에서 Fun1을 얻을 수 있습니다. file2에서 Hello Fun1 Hello Surprise !!! file1의 fun1을 file2의 fun1로 덮어 씁니다. 이렇게하지 않으려면 다음을 수행해야합니다.

declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello

fun1에 대한 이전 정의를 저장하고 가져올 필요가없는 이전 이름으로 복원합니다. 다른 파일에서 함수를 가져올 때마다 두 가지 측면을 기억할 수 있습니다.

  1. 동일한 이름으로 기존 이름을 덮어 쓸 수 있습니다 (원하는 경우 위에서 설명한대로 보존해야합니다).
  2. 가져 오기 파일의 모든 내용 (함수 및 전역 변수도 가져 오기)주의하세요! 위험한 절차

-5
#vi function.sh

#!/bin/bash
f1() {
    echo "Hello $name"
}

f2() {
    echo "Enter your name: "
    read name
    f1
}
f2

#sh function.sh

여기서 함수 f2는 함수 를 호출합니다.f1

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