쉘 스크립트를 실행하는 다른 방법


44

스크립트를 실행하는 몇 가지 방법이 있습니다.

/path/to/script # using the path (absolute or relative)
. script        # using the . (dot)
source script   # using the `source` command

이보다 더 많은가? 그들 사이의 차이점은 무엇입니까? 다른 것을 사용하지 말아야하는 상황이 있습니까?


아래의 질문과 답변, 특히 Shawn의 질문에 감사드립니다. 몇 가지 테스트를 실행할 때까지 나에게 분명하지 않은 것을 추가하고 싶습니다. 위의 두 번째 방법으로 "/"를 포함하면 명령이 위의 모드 1로 이동합니다. 즉, "./myscript.sh"는 모드 1을 따르지만 ". myscript.sh"는 모드 2에 고정됩니다. "경로 사용 (절대 또는 상대)"에 대해서는 언급했지만이 사실을 명백하게하고 싶었습니다.
Arun

답변:


32

또 다른 방법은 인터프리터를 호출하고 스크립트 경로를 전달하는 것입니다.

/bin/sh /path/to/script

도트와 소스는 동일합니다. (편집 : 아니오, 그렇지 않습니다 : KeithB가 다른 답변에 대한 의견에서 지적한 것처럼 "."은 bash 관련 셸에서만 작동합니다. "source"는 bash 및 csh 관련 셸 모두에서 작동합니다. -place (스크립트를 복사하여 붙여 넣은 것처럼). 이는 스크립트의 모든 함수 및 로컬이 아닌 변수가 남아 있음을 의미합니다. 또한 스크립트가 디렉토리에 CD를 넣는 경우에도 디렉토리에있을 수 있습니다.

스크립트를 실행하는 다른 방법은 자체 서브 쉘에서 실행합니다. 스크립트의 변수는 완료시 여전히 활성화되지 않습니다. 스크립트가 디렉토리를 변경 한 경우 호출 환경에 영향을 미치지 않습니다.

/ path / to / script와 / bin / sh 스크립트는 약간 다릅니다. 일반적으로 스크립트에는 처음에 다음과 같은 "shebang"이 있습니다.

#! /bin/bash

이것이 스크립트 인터프리터의 경로입니다. 인터프리터를 실행할 때와 다른 인터프리터를 지정하면 다르게 작동하거나 전혀 작동하지 않을 수 있습니다.

예를 들어 Perl 스크립트와 Ruby 스크립트는 (각각)으로 시작합니다.

#! /bin/perl

#! /bin/ruby

를 실행하여 해당 스크립트 중 하나를 실행 /bin/sh script하면 전혀 작동하지 않습니다.

우분투는 실제로 bash 쉘을 사용하지 않지만 dash라는 매우 유사한 것을 사용합니다. bash가 필요한 /bin/sh script스크립트는 대시 인터프리터를 사용하여 bash 스크립트를 방금 호출했기 때문에 호출하면 약간 잘못 작동 할 수 있습니다 .

스크립트를 직접 호출하고 스크립트 경로를 인터프리터에 전달하는 것의 또 다른 작은 차이점은 스크립트를 직접 실행하려면 스크립트를 실행 가능으로 표시해야하지만 경로를 인터프리터에 전달하여 실행해서는 안된다는 것입니다.

또 다른 사소한 변형 : 스크립트를 eval로 실행하기 위해 이러한 방법 중 하나를 접두어 사용할 수 있습니다.

eval sh script
eval script
eval . script

등등. 실제로 아무것도 변경되지는 않지만 철저하게 포함시킬 것이라고 생각했습니다.


6
"우분투는 실제로 bash 쉘을 사용하지 않는다"고 말하는 것은 정확하지 않으며 기술적으로 부정확합니다. 우분투 bash 쉘을 사용 하지만 요점은에 sh해당 dash하지만에 해당 하지 않습니다 bash.
Faheem Mitha

@Shawn firts para에서 "스크립트를 복사하여 붙여 넣는 것처럼 스크립트를 제자리에서 실행합니다. 이는 스크립트의 모든 함수와 로컬이 아닌 변수가 남아 있음을 의미합니다." 두 번째 줄은 무엇을 의미합니까? 설명해 주시겠습니까?
Geek

@Geek 스크립트를 자식 프로세스 (일반적인 방법)로 실행하면 프로세스가 종료 될 때 스크립트가 정의한 모든 변수 (환경)가 사라집니다. 스크립트를 소싱하면 해당 변수 및 함수가 현재 환경에서 작성됩니다. 스크립트가 끝나면 환경에 대한 변경 사항이 유지됩니다.
Shawn J. Goff

@ ShawnJ.Goff는 설명을 주셔서 감사합니다. +1.
Geek

플롯 트위스트 : Bourne Shell (sh)은 bash 내장 함수이므로 소스 만 허용하지 않습니다. pubs.opengroup.org/onlinepubs/9699919799/utilities/… 가장 휴대하기 쉬운 방법은 점입니다.
dezza

9

대부분의 사람들은 다음 디버깅 플래그 를 스크립트에 추가하여 쉘 스크립트를 디버그 합니다.

set -x     # Print command traces before executing command.
set -v     # Prints shell input lines as they are read.
set -xv    # Or do both

그러나 이것은 편집기로 파일을 열고 (파일을 편집 할 수있는 권한이 있다고 가정), 같은 줄을 추가 set -x하고 파일을 저장 한 다음 파일을 실행해야합니다. 그런 다음 동일한 단계를 수행하고 set -x등을 제거해야합니다 . 지루할 수 있습니다.

이를 수행하는 대신 명령 행에서 디버깅 플래그를 설정할 수 있습니다.

$ bash -x ~/bin/ducks
+ du -cks -x dir1 dir2 dir3 file1 file2 file3
+ sort -n
+ tail .ducks
123 etc
424 bin
796 total



$ sh -xv ~/bin/ducks  
#!/usr/bin/env bash

# Find the disk hog
# Borrowed from http://oreilly.com/pub/h/15
...
...

2
관련 팁 : 나는 emulate sh 2>/dev/null쉘 스크립트의 맨 위에 두는 습관에 들어갔다 . zsh와 함께 실행하면 POSIX 호환 모드가됩니다. 다른 쉘과 함께 실행할 때는 해당 라인이 적용되지 않습니다. 그런 다음로 스크립트를 실행할 수 있습니다 zsh -x /path/to/script. 나는 bash 또는 ksh보다 더 나은 추적을 제공하기 때문에 zsh를 좋아한다.
Gilles 'SO- 악마 그만

7

Shawn J. Goff는 많은 좋은 지적을했지만 전체 기사를 포함하지는 않았습니다.

우분투는 실제로 bash 쉘을 사용하지 않지만 dash라는 매우 유사한 것을 사용합니다. /bin/sh대시 인터프리터를 사용하여 bash 스크립트를 방금 호출했기 때문에 스크립트 를 수행하면 bash가 필요한 스크립트가 약간 잘못 작동 할 수 있습니다 .

init.d와 같은 / etc 등의 많은 시스템 스크립트는 shebang을 가지고 #!/bin/sh있지만 /bin/sh실제로는 /bin/bash요즘 다른 쉘과의 상징적 인 링크 /bin/dash입니다. 그러나 그중 하나가로 호출되면 /bin/sh다르게 동작합니다. 즉 POSIX 호환 모드를 고수합니다.

그들은 이것을 어떻게합니까? 글쎄, 그들은 어떻게 호출되었는지 검사합니다.

쉘 스크립트 자체가 어떻게 호출되었는지 테스트하고 그에 따라 다른 일을 할 수 있습니까? 예, 그럴 수 있습니다. 따라서 호출 방식은 항상 다른 결과로 이어질 수 있지만 물론 성가신 경우는 거의 없습니다. :)

일반적으로 bash와 같은 특정 셸을 배우고 bash 자습서에서 명령을 작성 하는 경우 달리 언급 된 경우를 제외하고 #!/bin/bash제목이 아닌을 입력하십시오 #!/bin/sh. 그렇지 않으면 명령이 실패 할 수 있습니다. 스크립트를 직접 작성하지 않은 경우 쉘 ( , ) 을 추측하는 대신 직접 스크립트 ( ./foo.sh, bar/foo.sh)를 호출하십시오 . shebang은 올바른 쉘을 호출해야합니다.sh foo.shsh bar/foo.sh

그리고 다른 두 가지 종류의 호출이 있습니다.

cat foo.sh | dash
dash < foo.sh

5

.그리고 source그들이 서브 프로세스를 생성하지만, 현재 쉘에서 명령을 실행하지 않는 점에서 동일합니다. 스크립트가 환경 변수를 설정하거나 현재 작업 디렉토리를 변경할 때 중요합니다.

경로를 사용하거나 경로를 지정 /bin/sh하면 명령이 실행되는 새 프로세스 가 작성됩니다.


2
sh script
bash script

더 많은 것이 있으면 숙고하고 있습니다 ...

.그리고 source동일합니다. 실행 후 환경 변경은 script유지됩니다. 일반적으로 Bash 라이브러리를 소싱하는 데 사용되므로 라이브러리를 다양한 스크립트에서 재사용 할 수 있습니다.

또한 현재 디렉토리를 유지하는 좋은 방법입니다. 스크립트에서 디렉토리를 변경하면 해당 스크립트를 실행하는 쉘에 디렉토리가 적용되지 않습니다. 그러나 스크립트를 종료 한 후에 소스를 실행하면 현재 디렉토리가 유지됩니다.


2
.sh / bash 및 관련 쉘에서만 작동합니다. sourcecsh 및 관련 쉘에서도 작동합니다.
KeithB

1

" userland exec "는 다른 방법으로 계산됩니까? Userland exec는 코드를로드하고 execve () 시스템 호출을 사용하지 않고 실행되도록합니다.


1
. ./filename
# ( dot space dot slash filename )

디렉토리가 경로에 없을 때 현재 쉘에서 스크립트를 실행합니다.


1

. 소스는 적어도 zsh에서 조금 다릅니다 (내가 사용하는 것).

source file

작동하는 동안

. file

필요하지 않습니다.

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