소싱("." 또는 "source")과 bash에서 파일 실행의 차이점은 무엇입니까?

소싱("." 또는 "source")과 bash에서 파일 실행의 차이점은 무엇입니까?

다음과 같은 스크립트를 실행할 때의 차이점은 무엇입니까?

./test.sh

다음과 같은 스크립트를 실행합니다.

. test.sh?

차이점을 찾을 수 있는지 확인하기 위해 간단한 두 줄 스크립트를 시도했습니다.

#!/bin/bash
ls

그러나 둘 다 동일한 정보를 . test.sh반환합니다 ../test.sh

답변1

./test.shtest.sh별도의 프로그램으로 실행됩니다. 파일이 .bashrc 로 test.sh시작 한다면 #!/bin/bash아마도 bash 스크립트일 것입니다. 그러나 그것은 완전히 다른 것일 수도 있습니다.

. ./test.shtest.sh실행 중인 bash 인스턴스에서 파일 코드를 실행합니다. 마치 내용 파일이 test.sh줄 대신 텍스트로 포함된 것처럼 작동합니다 . ./test.sh. (거의: $BASH_LINENO내장 함수의 값과 동작 등 몇 가지 세부 사항이 다릅니다 return.)

source ./test.shbash와 동일합니다 ( . ./test.sh다른 쉘에서는 source약간 다르거나 완전히 없을 수 있으며 .POSIX 표준에 포함됨).

./test.sh내장 스크립트를 사용하여 별도의 스크립트를 실행하는 것과 내장 스크립트를 포함하는 것의 가장 일반적인 차이점 .은 스크립트가 일부 환경 변수를 설정하는 경우 test.sh별도의 프로세스에서는 하위 프로세스의 환경만 설정된다는 것입니다. 스크립트에는 환경 변수가 설정됩니다. 단독 쉘 프로세스가 설정되었습니다. 호출 스크립트에 줄을 추가 foo=bar하고 마지막 test.shecho $foo차이점을 볼 수 있습니다.

$ cat test.sh
#!/bin/sh
foo=bar
$ ./test.sh
$ echo $foo

$ . ./test.sh
$ echo $foo
bar

답변2

첫 번째 방법은 스크립트를 하위 프로세스로 실행하는 것입니다. 반면 소스 코드(두 번째 방법)는 현재 셸에 모든 명령을 입력한 것처럼 스크립트를 실행합니다. 스크립트가 변수를 설정하면 설정된 상태로 유지되고, 스크립트가 종료되면 세션이 종료됩니다. help .리소스 문서를 참조하세요 .

답변3

내가 알아차린 또 다른 점은 다음과 같은 별칭이 있는 경우입니다.

# add into .bashrc_aliases
alias ls='ls -lht'

이렇게 하면 ./test.sh일반 ls출력(현재 쉘과 다른 PID)을 얻을 수 있습니다.

auraham@pandora:~/iso$ ./test.sh 
dsl-4.4.10.iso  test.sh
3136 # PID

. test.sh또는 다음을 사용하면 . ./test.sh더 자세한 출력(현재 쉘과 동일한 PID)을 얻을 수 있습니다 .

auraham@pandora:~/iso$ echo $$
2767 # shell PID

auraham@pandora:~/iso$ . test.sh 
total 50M
drwxrwxr-x  2 auraham auraham 4.0K Jul 30 15:41 .
-rwxrwxr-x  1 auraham auraham   32 Jul 30 15:41 test.sh
drwxr-xr-x 50 auraham auraham 4.0K Jul 30 15:30 ..
-rw-rw-r--  1 auraham auraham  50M Jul 28 17:24 dsl-4.4.10.iso
2767 # PID

답변4

일반적으로 a는 ./file파일을 가리키는 방법일 뿐입니다. 이 경우 PWD(현재 작업 디렉터리) 경로 뒤에 사용된 파일 이름이 오는 것과 같습니다.

$ pwd
/home/isaac/me/bin/

$ realpath ./file
/home/isaac/me/bin/file

줄 시작 부분의 경로(첫 번째 인수 또는 인수 0)는 파일 실행을 시도하도록 쉘에 신호를 보낼 수도 있습니다. 쉘 스크립트인 경우 쉘은 이를 로드하여 새로운 실행 환경에서 실행할 가능성이 높습니다. 다른 형식의 유효한 실행 파일인 경우 셸은 exec커널 명령을 통해 실행을 시도합니다.

명령줄에 초기 점을 추가하면(전체 인수가 0인 경우에만 유효) 이미 존재하는 동일한 실행 환경을 사용하여 쉘 스크립트(외부 실행 파일이 아님)를 로드할 수 있습니다.

$ . ./file        # that exact same file as above, now it is sourced
$ source ./file   # an equivalent (but longer) command.

물론 경로에 디렉터리가 설정되어 있지 않은 경우(점으로 시작하지 않음) 가져오려는 특정 파일을 찾기 위해 일부 검색이 필요합니다.

배쉬에서:

파일 이름에 슬래시가 포함되어 있지 않으면 PATH의 파일 이름을 사용하여 파일 이름이 포함된 디렉터리를 찾습니다.

또한 POSIX 모드에서는 PWD를 사용하여 filename주어진 값을 검색합니다.

관련 정보