it-swarm-ko.tech

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

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

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

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

44
phunehehe

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

/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 스크립트를 방금 호출했기 때문에 bash가 필요한 스크립트는 /bin/sh script를 수행하여 호출 할 때 약간 잘못 작동 할 수 있습니다.

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

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

eval sh script
eval script
eval . script

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

32
Shawn J. Goff

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

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
...
...
9
Stefan Lasiewski

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

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

Init.d와 같은/etc 등의 많은 시스템 스크립트에는 Shebang #!/bin/sh이 있지만 /bin/sh은 실제로 다른 Shell에 대한 심볼릭 링크입니다. 시간 /bin/bash, 요즘 /bin/dash. 그러나 그중 하나가 /bin/sh으로 호출되면 다르게 동작합니다. 즉 POSIX 호환 모드를 고수합니다.

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

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

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

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

cat foo.sh | dash
dash < foo.sh
7
user unknown

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

경로를 사용하거나 /bin/sh는 명령이 실행되는 새로운 프로세스를 만듭니다.

5
mouviciel
sh script
bash script

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

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

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

2
livibetter

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

source file

작동하는 동안

. file

필요하지 않습니다.

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

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

1
jrh_enginnering

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

1
Bruce Ediger