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

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

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

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



답변

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

/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

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


답변

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

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
...
...


답변

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


답변

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

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


답변

sh script
bash script

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

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

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


답변

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


답변

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

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