IT

$0 및 BASH_SOURCE 중에서 선택

itgroup 2023. 5. 28. 20:34
반응형

$0 및 BASH_SOURCE 중에서 선택

둘 중에서 어떻게 선택합니까?"$0"그리고."${BASH_SOURCE[0]}"

GNU의 이 설명은 저에게 큰 도움이 되지 않았습니다.

    BASH_SOURCE
    
 An array variable whose members are the source filenames where the
 corresponding shell function names in the FUNCNAME array variable are
 defined. The shell function ${FUNCNAME[$i]} is defined in the file
 ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}

참고: POSIX 호환 솔루션은 다음 답변을 참조하십시오.

${BASH_SOURCE[0]}(또는, 더 간단히 말하면,$BASH_SOURCE[1] )에는 모든 호출 시나리오에서 포함된 스크립트의 (비교적 상대적인) 경로가 포함되어 있습니다. 특히 스크립트가 원본인 경우에는 해당되지 않습니다.$0.

게다가, 찰스 더피가 지적했듯이,$0호출자가 임의의 값으로 설정할 수 있습니다.
반대로.$BASH_SOURCE 이름이 지정된 파일이 포함되지 않은 경우 비워둘 수 있습니다. 예:
echo 'echo "[$BASH_SOURCE]"' | bash

다음은 이를 보여주는 예입니다.

대본foo:

#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"

$ bash ./foo
[./foo] vs. [./foo]

$ ./foo
[./foo] vs. [./foo]

$ . ./foo
[bash] vs. [./foo]

$0POSIX 쉘 사양의 일부이지만,BASH_SOURCE이름에서 알 수 있듯이, 는 Bash에 특화되어 있습니다.


선택적 판독값: vs. :

Bash를 사용하면 요소를 참조할 수 있습니다.0스칼라 표기법을 사용하는 배열 변수: 쓰기 대신${arr[0]}당신은 쓸 수 있습니다.$arr즉, 변수를 스칼라인 것처럼 참조하면 인덱스에서 요소를 얻을 수 있습니다.0.

이 기능을 사용하면 다음과 같은 사실을 알 수 없습니다.$arr는 배열이며, 이것이 인기 있는 셸 코드 린터 shellcheck.net 가 다음과 같은 경고를 보내는 이유입니다(이 문서 작성 시점).

SC2128: 인덱스 없이 배열을 확장하면 첫 번째 요소만 제공됩니다.

참고 사항:이 경고는 도움이 되지만, 첫 번째 요소가 반드시 표시되는 것은 아니기 때문에 더 정확할 수 있습니다.구체적으로 인덱스의 요소입니다.0이 값이 반환되므로 첫 번째 요소의 인덱스가 더 높으면(Bash에서 가능) 빈 문자열을 얻을 수 있습니다. 시도해 보십시오.a[1]='hi'; echo "$a".
(반대로,zshever renegade는 모든 요소를 첫 번째 char.가 저장된 문자열로 구분하여 단일 문자열로 반환합니다.$IFS기본적으로 공백입니다.

모호하기 때문에 이 기능을 사용하지 않도록 선택할 수도 있지만 예측 가능하게 작동하며 실용적으로 다음 이외의 인덱스에 액세스할 필요가 거의 없습니다.0배열 변수의${BASH_SOURCE[@]}.


선택적 판독, 파트 2: 배열 변수가 실제로 여러 요소포함하는 조건은 무엇입니까?:

BASH_SOURCE함수 호출이 관련된 경우에만 여러 의 항목이 있으며, 이 경우 요소는 다음과 평행합니다.FUNCNAME호출 스택에 현재 있는 모든 함수 이름을 포함하는 배열입니다.

즉, 함수 내부에서${FUNCNAME[0]}중인 과 실행 중인 함수의 이름이 들어 있습니다.${BASH_SOURCE[0]}되어 있습니다.${FUNCNAME[1]}에는 현재 실행 중인 함수가 호출된 함수의 이름 등이 포함됩니다.

에서 $i스택 에서, 통화스 경의 우택 ▁of${FUNCNAME[$i+1]}포함:

  • main(가짜 함수 이름), 스크립트 파일이 직접 호출된 경우(예:./script)

  • source스크립트 파일이 원본인 경우(예: 유사 함수 이름).source ./script또는. ./script).

이러한 스크립트는 설명하는 데 도움이 될 수 있습니다.외부 스크립트는 중간 스크립트를 호출하고 내부 스크립트는 다음과 같이 호출합니다.

$ cat outer.sh
#!/usr/bin/env bash
./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './inner.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = ''
$BASH_SOURCE[2] = ''

을 그나스크호트다출변음경면하로으을로 source문:

$ cat outer.sh
#!/usr/bin/env bash
source ./middle.sh
$ cat middle.sh
#!/usr/bin/env bash
source ./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "\$0 = '$0'"
echo "\${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "\${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "\${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ ./outer.sh
$0 = './outer.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = './middle.sh'
$BASH_SOURCE[2] = './outer.sh'

휴성을위사용을 합니다.${BASH_SOURCE[0]} 그이정될때의그, 리고것고.$0그렇지않으면.그것이 주는

${BASH_SOURCE[0]:-$0}

, 히특, zsh고하면,$0가 스립트올파경포로함도라더하인 합니다.source

TL;DR 사용을 권장합니다.${BASH_SOURCE:-$0}가장 보편적인 변종으로서.

이전 답변은 좋지만 사용 시 주의해야 할 사항을 언급하지 않았습니다.${BASH_SOURCE[0]}를 " " ": " "로 호출하면 과 같이 됩니다.sh당신의 주장은sh는 에별이없으로 않습니다.bash 16 LTS에서 16.04.5 LTS, 그것다연과습다니었내결되음서은경우에▁(▁ubuntu▁(▁linked내▁to다▁it)에 연결되었습니다.dash)에서 실패할 수 있습니다.BASH_SOURCE변수가 비어 있거나 비어 있습니다.다음은 예입니다.

t.sh :

#!/usr/bin/env bash

echo "\$0:                     [$0]"
echo "\$BASH_SOURCE:           [$BASH_SOURCE]"
echo "\$BASH_SOURCE or \$0:    [${BASH_SOURCE:-$0}]"
echo "\$BASH_SOURCE[0] or \$0: [${BASH_SOURCE[0]:-$0}]"

(성공적으로) 실행:

$ ./t.sh
$0:                    [./t.sh]
$BASH_SOURCE:          [./t.sh]
$BASH_SOURCE or $0:    [./t.sh]
$BASH_SOURCE[0] or $0: [./t.sh]

$ source ./t.sh
$0:                    [/bin/bash]
$BASH_SOURCE:          [./t.sh]
$BASH_SOURCE or $0:    [./t.sh]
$BASH_SOURCE[0] or $0: [./t.sh]

$ bash t.sh
$0:                    [t.sh]
$BASH_SOURCE:          [t.sh]
$BASH_SOURCE or $0:    [t.sh]
$BASH_SOURCE[0] or $0: [t.sh]

그리고 마지막으로:

$ sh t.sh
$0:                    [t.sh]
$BASH_SOURCE:          []
$BASH_SOURCE or $0:    [t.sh]
t.sh: 6: t.sh: Bad substitution

이력서

세 변형인 보는바같와세이번변만형째시▁the,:만,${BASH_SOURCE:-$0}작동하고 모든 호출 시나리오에서 일관된 결과를 제공합니다.스크립트되지 않은 배열 변수를 첫 번째 배열 요소와 동일하게 참조하는 bash의 기능을 활용합니다.

언급URL : https://stackoverflow.com/questions/35006457/choosing-between-0-and-bash-source

반응형