bash 함수에서의 별명 범위 source aliases.sh

환경을 설정하기 위해 많은 별칭을 만드는 스크립트 (쓰기 권한이 없음)를 사용합니다. 내 환경을 설정하기 위해 bash 함수를 만들고 싶지만 별칭이 함수 본문에서 살아남지 않는 것 같습니다.

다음은 최소한의 예입니다.

# aliases.sh
alias fooAlias='echo "this will never work!"'  

.

# .bashrc
function setupLotsOfThings() {
    source aliases.sh
    fooAlias
}

.

이제 aliases.sh대화식으로 간단히 소스를 작성 하면 정상적으로 작동합니다.

[mycomputer]~/ $ source aliases.sh
[mycomputer]~/ $ fooAlias
this will never work!

그러나 대신 .bashrc에 정의 된 함수를 호출하면 정의를 소싱 한 후 별칭을 인식하지 못합니다.

[mycomputer]~/ $ setupLotsOfThings
-bash: fooAlias: command not found

무슨 일이야? alias함수에서 사용될 때 명령 의 범위에 대해 누락 된 것이 있습니까?

편집 : 나는 최소한의 예를 넘어서 세부 사항을 추가하여 내가 성취하려는 것에 약간의 빛을 비출 것입니다.

내 작업을 위해 클러스터 및 / 또는 그리드에서 많은 소프트웨어를 개발하고 실행합니다. 다른 gcc 버전, 특정 소프트웨어 릴리스, 구성 및 데이터 PATH 및 다양한 환경 변수와 같이 완전히 다른 환경이 필요한 여러 프로젝트가 있습니다. 관리자는 일반적으로 다른 기능이나 별명을 호출하거나 다양한 스크립트를 실행하는 쉘 기능 또는 별명을 정의하여 다양한 것을 설정하는 스크립트를 제공합니다. 저에게는 블랙 박스입니다.

하나의 명령으로 다양한 환경을 설정하고 싶습니다. 현재 나는 다음과 같은 일을한다.

[mycomputer]~/ $ source /some/environment/setup/script.sh
[mycomputer]~/ $ aliasToSetupSomeSoftwareVersion    #this was defined in the above
[mycomputer]~/ $ anotherAliasForOtherSoftware
[mycomputer]~/ $ source /maybe/theres/another/script.sh
[mycomputer]~/ $ runSomeOtherSetup      # this was defined in the new script

이러한 명령은 일반적으로 순서대로 실행해야합니다. 내 생각은 기본적으로 위의 줄을 함수 블록에 복사하는 것이지만 원래 예제에서 볼 수 있듯이 작동하지 않습니다. 대체 해결 방법은 환영 이상입니다!



답변

다른 해결책은 해당 명령을 기능 블록 대신 텍스트 파일에 붙여 넣는 것입니다. 다음과 같은 것 :

## This is needed to make the sourced aliases available
## within the script.
shopt -s expand_aliases

source /some/environment/setup/script.sh
aliasToSetupSomeSoftwareVersion
anotherAliasForOtherSoftware
source /maybe/theres/another/script.sh
runSomeOtherSetup

setup1.sh원하는 곳에 저장하십시오 . 트릭은 이 파일을 실행하지 않고이 파일 을 소싱 하는 것입니다.

$ source setup1.sh

그러면 스크립트에있는 별칭이 실행되고 현재 셸에서 별칭이 사용 가능해집니다.

이것을 다음에 추가하여 프로세스를 더 단순화 할 수 있습니다 .bashrc.

alias setupLotsOfThings="source setup1.sh"

이제setupLotsOfThings 함수에서 원하는 동작을 실행 하고 얻을 수 있습니다 .


설명

여기에는 두 가지 문제가 있습니다. 첫째, 별칭은 선언 된 함수에 사용할 수 없지만 해당 함수가 종료 된 후에 만 ​​스크립트에서 별칭을 사용할 수 없다는 것입니다. 둘 다 같은 섹션에 설명되어 있습니다 man bash.

expand_aliases 쉘 옵션이 shopt를 사용하여 설정되지 않는 한 쉘이 대화식이 아닌 경우 별명은 확장되지 않습니다 (아래 SHELL BUILTIN COMMANDS에서 shopt에 대한 설명 참조).

별명 정의 및 사용에 관한 규칙은 다소 혼동됩니다. Bash는 항상 해당 라인에서 명령을 실행하기 전에 하나 이상의 완전한 입력 라인을 읽습니다. 명령이 실행될 때가 아니라 명령을 읽을 때 별칭이 확장됩니다. 따라서 다른 명령과 동일한 행에 나타나는 별명 정의는 다음 입력 행을 읽을 때까지 적용되지 않습니다. 해당 행에서 별명 정의 뒤에 오는 명령은 새 별명의 영향을받지 않습니다. 이 동작은 기능이 실행될 때도 문제가됩니다. 함수 정의 자체가 복합 명령이기 때문에 함수가 실행될 때가 아니라 함수 정의를 읽을 때 별칭이 확장됩니다. 결과적으로 함수에 정의 된 별명은
해당 함수가 실행될 때까지 사용할 수 없습니다 .
안전을 위해 별명 정의를 항상 별도의 행에 두십시오. 그리고 명령에 별명을 사용하지 마십시오.

그러면 파일 실행과 소싱간에 차이가 있습니다. 기본적으로 스크립트를 실행하면 별도의 셸에서 실행되고 소싱하면 현재 셸에서 실행됩니다. 따라서 소스를 소싱 setup.sh하면 스크립트에서 실행하지 않는 것처럼 상위 셸에서 별칭을 사용할 수 있습니다.


답변

실제로, 함수가로드 된 후에 별명을 사용할 수 있습니다! 대화식 쉘 또는 .bashrc함수 실행 후 사용할 수 있습니다 .

제한 사항은 함수가 평가 될 때가 아니라 함수 정의를 읽을 때 함수 정의의 별명이 확장되는 것입니다. 이것은 bash의 한계입니다. 그래서 이것은 작동합니다 :

function setupLotsOfThings() {
    source aliases.sh
}
setupLotsOfThings
fooAlias

그러나 이것은 아닙니다.

function setupLotsOfThings() {
    source aliases.sh
}
function useTheAliases() {
    fooAlias
}
setupLotsOfThings
useTheAliases

함수 내에서 사용할 수 있고 함수를 구문 분석 한 후에 정의 할 수있는 별칭이 필요한 경우 대신 별칭을 사용하십시오. command내장 기능을 사용하여 동일한 이름의 함수에서 외부 명령을 호출 할 수 있습니다 .