Bash의 "source" 명령이 함수에서 호출될 때 다르게 동작하는 이유는 무엇입니까?

Bash의 "source" 명령이 함수에서 호출될 때 다르게 동작하는 이유는 무엇입니까?

다음과 같은 사용 가능한 barBash 스크립트가 주어지면...

echo :$#:"$@":

...그리고 다음 실행 가능한 fooBash 스크립트:

echo -n source bar:
source bar
echo -n source bar foo:
source bar foo

function _import {
  source "$@"
}

echo -n _import bar:
_import bar
echo -n _import bar foo:
_import bar foo

Bash 스크립트를 실행하면 다음 foo과 같은 출력이 표시됩니다 ./foo.

source bar::0::
source bar foo::1:foo:
_import bar::1:bar:
_import bar foo::1:foo:

내 질문은 다음과 같습니다.

  1. source_import직접 호출하지 않고 함수에서 Bash 명령을 호출할 때 왜 다른가요 ?
  2. sourceBash 명령의 동작을 정규화하는 방법은 무엇입니까 ?

저는 Fedora 버전 20에서 Bash 버전 4.2.47(1) 릴리스를 사용하고 있습니다.

답변1

문제는 source파일이 현재 환경에서 실행되기 때문입니다. 에서는 bash위치 인수가 제공되지 않으면 변경되지 않습니다. ~에서bash Bourne Shell 내장 함수매뉴얼 페이지:

. (일정 기간)

. 파일 이름[매개변수]

현재 쉘 컨텍스트의 파일 이름 인수에서 명령을 읽고 실행합니다. 파일 이름에 슬래시가 포함되어 있지 않으면 PATH 변수를 사용하여 파일 이름을 찾습니다. Bash가 POSIX 모드가 아닌 경우 $PATH에 파일 이름이 없으면 현재 디렉터리가 검색됩니다.인수가 제공되면 filename이 실행될 때 위치 인수가 됩니다. 그렇지 않으면 위치 매개변수는 변경되지 않고 그대로 유지됩니다.. 반환 상태는 마지막으로 실행된 명령의 종료 상태이거나, 명령이 실행되지 않은 경우 0입니다. 파일 이름을 찾을 수 없거나 읽을 수 없는 경우 반환 상태는 0이 아닙니다. 이 내장 함수는 소스 코드와 동일합니다.

POSIX 정의가리키다( sourcein의 동의어입니다):dotbash

쉘은 현재 환경에서 파일의 명령을 실행해야 합니다.

또한 KornShell 버전의 dot는 위치 인수로 설정되는 선택적 인수를 취할 수 있음을 설명합니다.

KornShell 버전의 dot은 위치 매개변수로 설정된 선택적 매개변수를 사용합니다. 이는 도트 스크립트가 함수와 동일하게 작동하도록 허용하는 유효한 확장입니다.

source bar따라서 내부 함수를 호출할 때 _import위치 인수를 제공하지 않으므로 변경되지 않습니다. 이는 _import함수 범위와 동일하며, $@포함 bar$#is입니다 1(실행 시 _import bar).

함수 범위 source bar밖에서 호출 하면 전역 범위(또는 스크립트) _import와 동일합니다 . foo이 경우 실행 중이므로 null 및 0인 인수 없이 ./foo실행 중입니다 .foo$@$#

답변2

Gnouc의 답변은 내 첫 번째 질문에 대해 설명합니다. "직접 호출하는 대신 _import 함수에서 Bash의 소스 명령을 호출할 때 왜 다른가요?"

두 번째 질문에 대해서는 "Bash 소스 명령의 동작을 정규화하는 방법은 무엇입니까?"입니다.

아래에서 답을 찾은 것 같습니다.

_import기능을 다음과 같이 변경 하면 됩니다 .

function _import {
  local -r file="$1"
  shift
  source "$file" "$@"
}

Bash 스크립트를 실행하면 다음 foo과 같은 출력이 표시됩니다 ./foo.

source bar::0::
source bar foo::1:foo:
_import bar::0::
_import bar foo::1:foo:

내 질문과 이 답변의 근거는 다음과 같습니다. "가져온" Bash 스크립트는 가져오기 시 매개변수가 제공되지 않은 경우에도 Bash의 위치 및 특수 매개변수를 통해 자체 매개변수 세트를 평가할 수 있어야 합니다. 가져온 Bash 스크립트에 전달할 수 있는 모든 인수는 가져온 Bash 스크립트에 암시적으로 전달될 수 없습니다.

관련 정보