참조된 쉘 스크립트를 실행하지 않고 한 쉘 스크립트의 변수를 다른 쉘 스크립트에서 가져오기

참조된 쉘 스크립트를 실행하지 않고 한 쉘 스크립트의 변수를 다른 쉘 스크립트에서 가져오기

2개의 쉘 스크립트(file1.sh 및 file2.sh)가 있습니다.

파일1.sh

#!/usr/bin/env bash 
export var1="/data/share"
export var2='password'
echo "Hello"

파일2.sh

#!/usr/bin/env bash 
source file1.sh
echo $var1
echo $var2

file2.sh를 실행하면 다음과 같은 결과가 나타납니다.

Hello
/data/share
password

하지만 내 예상 결과는

/data/share
password

file2.sh에서 참조되면 file1.sh가 실행됩니다. file1.sh를 실행하지 않고 file2.sh에서 변수만 가져오려면 어떻게 해야 합니까?

답변1

소스가 제공될 때와 실행될 때 다르게 동작하려는 bash 스크립트가 있을 때(즉, 코드를 실행하지 않고 액세스하려는 스크립트에 데이터 항목이 있을 때) 사용하는 세 가지 옵션이 있습니다. 시간). 댓글은 어느 정도 그들에게 영향을 미쳤습니다.

옵션 1

소싱 시점을 결정하고 적절한 시점에 '소싱'을 종료합니다.

스크립트를 두 섹션으로 분리하고 두 번째 섹션으로 이동하기 전에 소스가 제공되면 스크립트를 종료합니다.

정의(함수/변수 할당/등)를 사용하여 스크립트의 상위 섹션을 생성하지만 직접적인 코드 실행은 하지 않습니다.

실행 가능한 코드 섹션이 시작되기 직전에 스크립트가 소싱되는 것을 감지하면 스크립트를 종료하는 로직을 배치합니다. 다음 코드 세그먼트가 이 작업을 수행합니다.


파일1.sh

#!/usr/bin/env bash
export var1="/data/share"
export var2='password'    
# --- End Definitions Section ---    
# check if we are being sourced by another script or shell
[[ "${#BASH_SOURCE[@]}" -gt "1" ]] && { return 0; }
# --- Begin Code Execution Section ---
echo "Hello"
echo $var1
echo $var2 


파일2.sh

#!/usr/bin/env bash 
source file1.sh
echo "$var1"
echo "$var2"


./file2.sh 실행 결과

$ ./file2.sh 
/data/share
password

옵션 2

이것은 일반적으로 복잡한 상황에서만 사용되며 이 특정 예에서는 과잉입니다. 소스로 사용하려는 파일에 함수를 만들고 해당 함수에서 호출자가 사용할 수 있는 항목을 결정합니다. 이 경우에는 내보낸 두 변수입니다. 일반적으로 나는 연관 배열이 있을 때 이 모드를 사용하는데, 그렇지 않으면 거의 다룰 수 없습니다. 또한 호출자가 tmp 파일을 삭제해야 합니다. 하지만 이번 경우에는 그러지 않았습니다.


파일1.sh

#!/usr/bin/env bash 
export var1="/data/share"
export var2='password'
exportCfg() {
  tmpF=$(mktemp)
  declare -p var1 var2 > "$tmpF"
  echo "$tmpF"
}
if [ "$1" == "export" ]; then
  exportCfg;
  exit 0;
fi

echo "Hello"
echo $var1
echo $var2


파일2.sh

#!/usr/bin/env bash 
source $(./file1.sh export)


echo "$var1"
echo "$var2"

file2.sh 실행 결과는 위와 동일합니다.

옵션 3

내가 이것을 처리하는 마지막 일반적인 방법은 정의만 보유하고 소스로 제공되거나 직접 실행될 때 실행되는 코드가 없는 라이브러리 파일을 사용하는 것입니다. 이것은 단순히 코드를 나누는 문제입니다. 나는 자주 사용되는 기능을 포함하는 bash 'libs' 그룹을 가지고 있으며 프로젝트별로 일반적으로 구성 데이터(상수)를 저장하기 위한 작은 소스 가능 라이브러리를 설정합니다. 해당 데이터에 채워진 배열이 포함되어 있으면 옵션 2 버전도 사용하겠습니다.

답변2

변수를 모두 같은 방식으로 내보내는 경우(foo=bar 내보내기), 다음을 사용하여 쉽게 모두 소싱할 수 있습니다.세게 때리다프로세스 대체 기능:

source <(grep '^export .*=' file1.sh)

맨페이지 추출:

프로세스 대체 프로세스 대체는 명명된 파이프(FIFO) 또는 열린 파일 이름을 지정하는 /dev/fd 방법을 지원하는 시스템에서 지원됩니다. <(목록) 또는 >(목록) 형식을 취합니다. 프로세스 목록은 FIFO 또는 /dev/fd의 일부 파일에 연결된 입력 또는 출력으로 실행됩니다. 이 파일의 이름은 확장 결과로 현재 명령에 인수로 전달됩니다. >(list) 형식을 사용하는 경우 파일에 쓰면 목록에 대한 입력이 제공됩니다. <(list) 형식을 사용하는 경우 인수로 전달된 파일을 읽어야 목록의 출력을 얻을 수 있습니다.

관련 정보