다른 쉘 스크립트에서 하나의 쉘 스크립트를 호출하는 방법은 무엇입니까?


737

나는 두 개의 쉘 스크립트를 가지고 a.shb.sh.

b.sh쉘 스크립트 내에서 어떻게 호출 할 수 a.sh있습니까?


8
어떤 OS와 어떤 쉘 (들) 또는 그 문제에 대해 원칙적으로 이야기하고 있습니까? 예제 코드도 도움이 될 것입니다.
jsalonen

14
이것은 실제로 특정 질문이 아니며 문제를 해결하기위한 사전 노력을 보여주지 않습니다.
Kris

1
내가 겪고있는 한 가지 문제 b.sh는 실행 권한이 없다는 것입니다. 확인하는 것이 좋습니다.
seth10

./스크립트 이름 앞에 추가 하십시오 (예 : 대신) b.sh:./b.sh
Benny

1
사람이 점점 계속 경우 No such file or directory오류 stackoverflow.com/a/2920431/1356559을
아 므르 Lotfy에게

답변:


957

이 작업을 수행 할 수있는 몇 가지 방법이 있습니다.

  1. 다른 스크립트를 실행 가능하게 만들고 #!/bin/bash맨 위에 줄을 추가 하고 파일이 $ PATH 환경 변수에 대한 경로를 추가하십시오 . 그런 다음 일반 명령으로 호출 할 수 있습니다.

  2. 또는 다음과 같이 source명령 (별칭은 .)으로 호출하십시오 . source /path/to/script;

  3. 또는 bash명령을 사용하여 실행하십시오. /bin/bash /path/to/script;

첫 번째 및 세 번째 방법은 스크립트를 다른 프로세스로 실행하므로 다른 스크립트의 변수 및 함수에 액세스 할 수 없습니다.
두 번째 방법은 첫 번째 스크립트 프로세스에서 스크립트를 실행하고 다른 스크립트에서 변수 및 함수를 가져 와서 호출 스크립트에서 사용할 수 있도록합니다.

두 번째 방법에서는 exit두 번째 스크립트를 사용 하는 경우 첫 번째 스크립트도 종료됩니다. 첫 번째와 세 번째 방법에서는 발생하지 않습니다.


30
chmod a+x /path/to/file실행 가능하지 않다는 것을 기억하십시오 . ./script 메소드에만 적용됩니다.
Nathan Lilienthal 2014 년

3
그들은 DOS에서 만든 다음 유닉스 환경에 업로드하는 경우 유닉스에서 실행 파일의 인코딩 / 변경 형식으로 기억 -> DOS2UNIX <스크립트 이름>
아비 쉑 차 터지

3
@cecemel 첫 번째 및 세 번째 방법 일반적인 백그라운드에서 실행 구문을 사용하여 "비동기" 있습니다.
일부 프로그래머 친구

16
문제 는 호출 된 스크립트 sourceexit문장이 당신을 종료한다는 것입니다.
Ohad Schneider

18
@ user528025 .는에 대한 별칭이 source아니라 오히려 다른 방법입니다. POSIX 호환 쉘에서 작동 source하는 동안 bash 확장 .입니다.
Score_Under

207

이것 좀 봐.

#!/bin/bash
echo "This script is about to run another script."
sh ./script.sh
echo "This script has just run another script."

4
이는 script.sh가 실행중인 스크립트와 동일한 디렉토리에 있다고 가정합니다. 다른 곳에서 스크립트를 호출하려면 다음과 같이 말하십시오.sh <path to script>/script.sh
Morgan Kenyon

32
이것은 또한 사용 포탄을 bash하고 sh. sh사실 bash일 때도 동일하게 동작하지 않습니다. 당신이 사용하고 있다면 #!/bin/bash아마도 사용하고 싶을 것입니다 bash script.sh(또는 단지 ./script.sh그 스크립트의 hashbang을 사용하고 싶습니다).
Martin Tournoij

1
chmod +x.sh 파일로 설정해도 권한 거부 오류가 발생했습니다 . 어떤 제안?
isaac 님이

@isaacweathers 시도 chmod 777
Janac Meena

114

이를 수행 할 수있는 몇 가지 방법이 있습니다. 스크립트를 실행할 터미널 :

#!/bin/bash
SCRIPT_PATH="/path/to/script.sh"

# Here you execute your script
"$SCRIPT_PATH"

# or
. "$SCRIPT_PATH"

# or
source "$SCRIPT_PATH"

# or
bash "$SCRIPT_PATH"

# or
eval '"$SCRIPT_PATH"'

# or
OUTPUT=$("$SCRIPT_PATH")
echo $OUTPUT

# or
OUTPUT=`"$SCRIPT_PATH"`
echo $OUTPUT

# or
("$SCRIPT_PATH")

# or
(exec "$SCRIPT_PATH")

이 모든 것은 공백이있는 경로에 맞습니다 !!!


41
차이점은 무엇입니까? 왜, 왜 또?
로켓 스페이서

. "$ SCRIPT_PATH"선호
Harry Mumford-Turner

1
sh "$ SCRIPT_PATH"및 bash "$ SCRIPT_PATH"는 #! / usr / bin / expect 스크립트를 실행하지 않는 반면 "$ SCRIPT_PATH"는 그렇지 않습니다.
Tahlor

58

내가 찾은 대답 :

( exec "path/to/script" )

언급 한대로 exec새 프로세스를 작성하지 않고 쉘을 대체합니다. 그러나 , 우리는 그것을 서브 쉘에 넣을 수 있으며, 이것은 패 리언을 사용하여 수행됩니다.

편집 : 실제로 ( "path/to/script" )충분합니다.


11
이것은 꽤 복잡한 것처럼 보입니다. 그냥 전화 해 보지 않겠 /path/to/script습니까? 나는 exec여기에 전혀 필요가 보이지 않습니까?
Martin Tournoij

서브 쉘은 필요하지 않기 때문에 필요하지 않습니다 exec.
Karel Vlk

6
이 스크립트를 인수와 함께 어떻게 실행 하시겠습니까?
Bhargav

여전히 하위 스크립트의 출력을 캡처하려면 $ (source "path / to / script")
cmcginty

@Bhargav는이 링크를 따르십시오 stackoverflow.com/questions/14302389/…
tpbafk

16

에 따라 다릅니다. 간단히 ... 현재 콘솔에서 변수를로드하고 실행하려면 source myshellfile.sh코드에서 사용할 수 있습니다. 예:

!#/bin/bash
set -x
echo "This is an example of run another INTO this session."
source my_lib_of_variables_and_functions.sh
echo "The function internal_function() is defined into my lib."
returned_value=internal_function()
echo $this_is_an_internal_variable

set +x

파일을 실행하고 싶지만 결과를 얻는 유일한 결과는 다음과 같습니다.

!#/bin/bash
set -x
./executing_only.sh
sh i_can_execute_this_way_too.sh
bash or_this_way.sh
set +x

희망이 있습니다. 감사.


2
참고 source떠들썩한 고유의 기능입니다. 표준 본 쉘에는 .(예 :) 만 있습니다 . other_script.sh.
Martin Tournoij

15

/bin/sh실제 스크립트를 통해 다른 스크립트를 호출하거나 실행 하는 데 사용할 수 있습니다 .

 # cat showdate.sh
 #!/bin/bash
 echo "Date is: `date`"

 # cat mainscript.sh
 #!/bin/bash
 echo "You are login as: `whoami`"
 echo "`/bin/sh ./showdate.sh`" # exact path for the script file

결과는 다음과 같습니다.

 # ./mainscript.sh
 You are login as: root
 Date is: Thu Oct 17 02:56:36 EDT 2013

1
분명히 이것은 showdate.sh/ bin / bash가 아닌 / bin / sh에서 실행 됩니까?
Chris Watts

" /bin/sh ./showdate.sh", " /bin/bash ./showdate.sh", " ./showdate.sh"로 시도하고 mainscript.sh 파일을 실행하고 동일한 출력을 얻었습니다.
Ranjithkumar T

10

터미널에 입력 한 내용을 줄에 추가하여 스크립트를 실행하십시오!
예 :

#!bin/bash
./myscript.sh &

실행할 스크립트가 동일한 디렉토리에 있지 않은 경우 스크립트의 전체 경로를 사용하십시오.
예 :`/ home / user / script-directory /./ myscript.sh &


&백그라운드 작업을위한 @Carpetsmoker
Andrei Krasutski

9

먼저 호출 한 파일을 포함시켜야합니다.

#!/bin/bash
. includes/included_file.sh

그런 다음 함수를 다음과 같이 호출하십시오.

#!/bin/bash
my_called_function

9

간단한 소스가 도움이 될 것입니다. 예를 들어.

#!/bin/bash
echo "My shell_1"
source my_script1.sh
echo "Back in shell_1"

9

동일한 디렉토리에 다른 파일이 있으면 다음 중 하나를 수행하십시오.

bash another_script.sh

또는

source another_script.sh

또는

. another_script.sh

bash대신에 source스크립트 를 사용 하면 스크립트가 상위 스크립트의 환경을 변경할 수 없습니다. 이 .명령은 POSIX 표준이지만 sourcecommand는 더 읽기 쉬운 bash 동의어입니다 .(나는 선호 source합니다 .). 스크립트가 다른 곳에 상주하는 경우 해당 스크립트의 경로를 제공하십시오. 상대 경로와 전체 경로가 모두 작동해야합니다.


5

상단 답변은 #!/bin/bash호출되는 하위 스크립트의 첫 번째 줄에 줄을 추가 할 것을 제안 합니다. 당신이 오두막을 추가 할 경우에도, 그것은 훨씬 빠릅니다 * 서브 쉘 스크립트를 실행하고 출력을 캡처 :

$(source SCRIPT_NAME)

이것은 동일한 인터프리터를 계속 실행하려고 할 때 (예 : bash에서 다른 bash 스크립트로) 하위 스크립트의 shebang 행이 실행되지 않도록합니다.

예를 들면 다음과 같습니다.

#!/bin/bash
SUB_SCRIPT=$(mktemp)
echo "#!/bin/bash" > $SUB_SCRIPT
echo 'echo $1' >> $SUB_SCRIPT
chmod +x $SUB_SCRIPT
if [[ $1 == "--source" ]]; then
  for X in $(seq 100); do
    MODE=$(source $SUB_SCRIPT "source on")
  done
else
  for X in $(seq 100); do
    MODE=$($SUB_SCRIPT "source off")
  done
fi
echo $MODE
rm $SUB_SCRIPT

산출:

~ ❯❯❯ time ./test.sh
source off
./test.sh  0.15s user 0.16s system 87% cpu 0.360 total

~ ❯❯❯ time ./test.sh --source
source on
./test.sh --source  0.05s user 0.06s system 95% cpu 0.114 total

* 예를 들어 바이러스 나 보안 도구 장치에서 실행되는 경우는 새로운 프로세스를 간부 인을 추가 100ms에 걸릴 수 있습니다.


4
pathToShell="/home/praveen/"   
chmod a+x $pathToShell"myShell.sh"
sh $pathToShell"myShell.sh"

4
 #!/bin/bash

 # Here you define the absolute path of your script

 scriptPath="/home/user/pathScript/"

 # Name of your script

 scriptName="myscript.sh"

 # Here you execute your script

 $scriptPath/$scriptName

 # Result of script execution

 result=$?

1
공백이있는 폴더 scriptPath또는 파일 이름에 올바르지 않음scriptName
Andrei Krasutski

3

새 파일이 "/ home / satya / app / app_specific_env"이고 파일 내용이 다음과 같다고 가정합니다.

#!bin/bash

export FAV_NUMBER="2211"

~ / .bashrc 파일에이 파일 참조를 추가하십시오

source /home/satya/app/app_specific_env

컴퓨터를 다시 시작하거나 다시 로그인 할 때 echo $FAV_NUMBER마다 터미널에서 시도 하십시오. 값을 출력합니다.

source ~/.bashrc명령 행에서 즉시 효과를보고자하는 경우에 대비합니다 .


3
chmod a+x /path/to/file-to-be-executed

그게 내가 필요한 유일한 것이었다. 실행될 스크립트가 이와 같이 실행 가능 해지면, 적어도 (내 경우에는) 스크립트를 호출하는 동안 sh이나 ./스크립트를 호출하는 동안 다른 추가 작업이 필요하지 않습니다 .

@Nathan Lilienthal의 의견 덕분에


1

다른 파일에서 함수를 가져 오는 데 문제가 있습니다.
첫째 :이 파일을 실행할 필요가 없습니다. 그렇게하지 않는 것이 좋습니다! 그냥 추가

. file

모든 기능을 가져옵니다. 그리고 그것들은 마치 파일에 정의 된 것처럼 될 것입니다.
둘째 : 같은 이름으로 함수를 정의 할 수 있습니다. 덮어 씁니다. 그것은 나쁜. 그렇게 선언 할 수 있습니다

declare -f new_function_name=old_function_name 

그 후에 만 ​​가져옵니다. 따라서 새로운 이름으로 이전 함수를 호출 할 수 있습니다.
셋째 : 파일에 정의 된 전체 기능 목록 만 가져올 수 있습니다. 필요하지 않은 일부는 설정을 해제 할 수 있습니다. 그러나 설정 해제 후 함수를 다시 작성하면 기능이 손실됩니다. 그러나 위에서 설명한대로 참조를 설정하면 동일한 이름으로 설정을 해제 한 후 복원 할 수 있습니다.
드디어일반적인 수입 절차에서 위험하고 그렇게 간단하지 않습니다. 조심해! 더 쉽고 안전하게 스크립트를 작성할 수 있습니다. 함수의 일부만 사용하는 경우 (모두는 아님) 다른 파일로 분할하는 것이 좋습니다. 불행히도이 기술은 bash에서 잘 이루어지지 않았습니다. 예를 들어 파이썬과 다른 스크립트 언어에서는 쉽고 안전합니다. 자체 이름을 가진 필요한 기능 만 부분적으로 가져올 수 있습니다. 우리는 다음 부시 버전에서도 동일한 기능을 수행하기를 원합니다. 그러나 지금 우리는 당신이 원하는 것을하기 위해 많은 추가 대구를 작성해야합니다.


(SO에 오신 것을 환영합니다!) 사용자로서 프라 빈은 지난 2011 년 보였다, 질문인지 분류하기 어려울 수밖에 없다 쉘이 실행하는 방법을 a.sh이 실행 b.sh을 (그리고 실행을 계속 a.sh을 하지 않을 경우 그렇지 않으면 명령 , 또는 문자로) 호출 b.sh . (내 맞춤법 검사기는 캐치하지 않습니다 bush versions.) (영어 문법에 도움을 위해 설정하는 사람이 있는가 (가끔 있었으면 좋겠다)?.)
수염이 희끗 희끗 한

0

백틱을 사용하십시오.

$ ./script-that-consumes-argument.sh `sh script-that-produces-argument.sh`

그런 다음 생산자 스크립트의 출력을 소비자 스크립트의 인수로 가져옵니다.

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