bash 스크립트를 실행하는 동안 모듈을로드 할 수 없지만 소싱 할 때만 모듈을로드 할 수없는 이유는 무엇입니까?


13

시스템에서 패키지를 제어하기 위해 모듈 을 사용 python/2.7.2하고 있으며 모듈로 설치했습니다. python_exe.py간단한 '구동'스크립트에서 호출 할 간단한 파이썬 실행 파일 이 있습니다 runit.sh. runit.sh스크립트는 다음과 같습니다.

#!/bin/bash
module load python/2.7.2
arg1=myarg1
arg2=15
arg3=$5
/path/to/python_exe.py -a $arg1 -b $arg2 -c $arg3

그러나 방금 실행 ./runit.sh하면 "module : command not found"가 나옵니다 . 그러나 I source runit.sh이면 모듈을 올바르게로드합니다. 왜 이런거야?

답변:


13

module명령이 별명 또는 쉘 기능 이기 때문에 ( module (1)의 " 패키지 초기화 " 참조 ) 이라고 말하면 대화식 쉘에 명령을 직접 입력하는 것과 같습니다 . 그러나 당신이 말할 때 , 당신은 새로운 비대화 형 쉘을 실행하고 있습니다. 비 대화식 쉘에는 일반적으로 표준 별명 및 쉘 기능이 설정되어 있지 않습니다.source runit.shmodule./runit.sh

module (1) 은 다음과 같이 말합니다.“ 쉘 전용 초기화 스크립트가 쉘에 공급되면 모듈 패키지와 모듈 명령이 초기화됩니다. 스크립트 는 별명 또는 쉘 함수로 모듈 명령을 작성합니다 .…” module스크립트 에서 명령 을 실행해야하는 경우 스크립트에서 module명령 및 명령 을 정의하는 초기화 스크립트를 찾으십시오 source.


이것이 .bashrc와 .bash_profile을 사용하는 것의 차이점입니까? 이들 중 하나만 사용하기 위해 모듈 시스템을 시작하는 초기화 루틴이 있습니다.
drjrm3

나는 당신이 무엇을 요구하는지 정확히 모르겠습니다. 그러나 : bash는 기본적으로 다음 (이러한 행동이 옵션에 의해 대체 될 수 있습니다)을 수행 : 로그인 쉘이`~ / .bash_profile`하지만 읽고 ~/.bashrc, 로그인 쉘이 아닌 대화 형 쉘 (예를 들어, 당신이 무엇을 얻을 당신이 입력하는 경우 bash로 명령)은 읽지 ~/.bashrc만 읽지 않고 ~/.bash_profile비 대화식 쉘 (예 : 스크립트를 실행하는 쉘)은 읽지 않습니다. … (계속)
Scott

(계속)… 이것은 아마도 Cyrus가 제안한 이유 일 것입니다 #!/bin/bash -i. -i옵션이 쉘을 대화식으로 만들어서 읽을 수 있기 때문 ~/.bashrc입니다. IMHO는 대화식 모드에 쓸 수없는 수하물이있을 수 있기 때문에 과잉 ~/.bash_history입니다. 반면에 module셸 함수가 아닌 별칭으로 정의 된 경우 대화 형이 아닌 쉘에서는 작동하지 shopt -s expand_aliases않으므로 Cyrus의 대답이 가장 좋습니다.
Scott

4

시스템에서 쉘의 간단한 호출은 정의 된 별칭 (또는 함수)을 상속하지 않으므로 module쉘이 찾을 수 없습니다 (발췌 부분은 아래 참고 참조). 시도 type module하는 방법을 확인하려면 프롬프트에서 module이 현재 정의된다.

기본적으로 소스 를 사용하는 것은 키보드에서 스크립트의 각 줄을 쓰는 것과 같습니다.
한쪽에서는 현재 쉘의 모든 특정 히스토리를 상속하지만 다른 쪽에서는 현재 쉘이 스크립트 및 module호출 의 모든 부작용에 영향을 받습니다.

스크립트를 소스에 그것을 실행의 차이점 은 슈퍼 유저에 읽을 수 2009년 9월 또는 2009년 12월 , 우분투 2011년 2월 , 유닉스 2011년 8월 , 유래 2012 12월 또는 여러 다른 장소에서합니다.

이와 관련하여 Modulefiles 섹션 에는 경고가 있습니다 .

... 모듈 파일을 언로드 할 때 환경 변수가 설정되지 않습니다. 따라서 환경 변수가 이전 상태로 돌아 가지 않고 모듈 파일을로드 한 다음 언로드 할 수 있습니다.

따라서 스크립트에서 실행하는 것이 더 현명 해 보입니다 .

후자를 달성하기 위해 나는 생각할 수 있습니다 :

  1. 대화식 쉘 을 사용하려면 현재 쉘의 특정 히스토리를 무시하고 다음 과 같이 스크립트 의 shebang 을 수정하십시오.

    #!/bin/bash -i

    대화식 쉘은 tty의 사용자 입력에서 명령을 읽습니다. 무엇보다도 이러한 쉘은 활성화시 시작 파일을 읽고 프롬프트를 표시하며 기본적으로 작업 제어를 활성화합니다 ...

  2. 대신 현재 쉘의 특정 스토리를 상속하려는 경우 소스 쉘을 시도 할 수 있지만 서브 쉘에서

    ( source runit.sh )
  3. 현재의 별칭 / 기능을 찾아보십시오 moduletype module다음 결과에 스크립트를 수정합니다. 일부 환경 변수는로 설정할 수 없습니다 module.
    원하는 경우 디렉토리에서 초기화 스크립트를 찾을 수 있습니다 $MODULESHOME/init/<shell>.


코멘트
에 기억하고 모듈 Q & A

하위 프로세스 (스크립트)는 상위 프로세스 환경을 변경할 수 없습니다. 스크립트의 모듈로드는 스크립트 자체의 환경에만 영향을줍니다. 스크립트가 현재 환경을 변경할 수있는 유일한 방법은 스크립트를 현재 프로세스로 읽는 스크립트를 소싱하는 것입니다.

따라서 현재 환경을 수정하지 않으려면 shebang 을 변경 하거나 (1) 하위 셸 에서 스크립트를 소싱하는 것이 좋습니다 (2). 나는 사건의 유용성에 대해 완전히 확신하지 못한다 (3).


참고 모듈의
매뉴얼 및 설명 페이지에서 발췌

module모듈 패키지에 대한 사용자 인터페이스입니다. module별칭 또는 기능은 실행 modulecmd프로그램을 쉘 명령의 출력을 평가하고있다. modulecmd쉘 유형 을 지정하는 첫 번째 인수 입니다.

쉘 특정 초기화 스크립트가 쉘에 소스 될 때 모듈 패키지 및 module명령 이 초기화됩니다 . 스크립트는 별명 또는 쉘 함수로 모듈 명령을 작성하고 모듈 환경 변수를 작성합니다.


그러나 그는 부모 프로세스의 환경에 영향을 미치지 않습니다. 그는 파이썬 실행 파일을 스크립트에서 실행하려고합니다 . 게다가, 당신의 대답은 왜 그가“module : command not found”에러 메시지를 얻는 지 설명하지 않습니다.
Scott

@Scott 감사합니다. 실수로 답변의 더 큰 부분을 잘라 내고 조각 만 게시했습니다. 답변이 다시 작성되었습니다.
Hastur

1
+1.  ( source runit.sh )좋은 대답입니다. 나는 그것을 생각하지 않았다. 그리고 좋은 참고 자료 모음.
Scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.