Por que não consigo carregar módulos durante a execução do meu script bash, mas apenas ao fazer o sourcing?

11

Estou usando módulos para controlar os pacotes no meu sistema e tenho python/2.7.2 instalado como um módulo. Eu tenho o executável python simples python_exe.py que eu vou chamar de um simples script de 'condução' runit.sh . O script runit.sh é parecido com:

#!/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

No entanto, quando eu executo ./runit.sh , ele me vende "module: command not found". Quando eu source runit.sh , no entanto, ele carrega corretamente o módulo. Por que isso acontece?

    
por drjrm3 07.04.2015 / 20:54

2 respostas

10

Como o comando module é um alias ou uma função shell (veja " Inicialização do pacote " em módulo (1) ). Quando você diz source runit.sh , é como digitar o comando module diretamente no seu shell interativo. Mas quando você diz ./runit.sh , você está executando um novo shell não interativo. Conchas não interativas geralmente não possuem os aliases padrão e as funções do shell configuradas.

módulo (1) diz: “O pacote de módulos e o comando module são inicializados quando um script de inicialização específico do shell é originado no shell. O script cria o comando module , como um alias ou função de shell,… ” Se você precisar executar o comando module em um script, encontre o script de inicialização que define o comando module e source do script.

    
por 07.04.2015 / 21:45
4

Parece que a invocação simples do shell em seu sistema não herda o alias (ou a função) com o qual é definido module , então o shell não é capaz de encontrá-lo (veja abaixo a nota com os trechos ). Tente type module no prompt para ver como o module está atualmente definido.

Essencialmente com source é como se você escrevesse cada linha do script pelo teclado.
Observe que, de um lado, você está herdando todo o histórico específico do shell atual, mas, por outro, o shell atual será submetido a todos os lados do seu script e module de invocação.

Sobre as diferenças entre criar um script e executá-lo você pode ler em SuperUser Set 2009 ou Dez 2009 , Ubuntu Fev 2011 , Unix agosto de 2011 , Stackoverflow Dez / 2012 ou em muitos outros lugares.

A esse respeito, na seção Modulefiles , há um aviso :

... Environment variables are unset when unloading a modulefile. Thus, it is possible to load a modulefile and then unload it without having the environment variables return to their prior state.

Portanto, parece mais sensato executá-lo em um script .

Para realizar o último, posso pensar:

  1. Para usar um shell interativo , negligenciando o histórico específico do shell atual, modificando o shebang do seu script com

    #!/bin/bash -i
    

    An interactive shell reads commands from user input on a tty. Among other things, such a shell reads startup files on activation, displays a prompt, and enables job control by default...

  2. Se preferir herdar a história específica do presente shell, você pode tentar obtê-lo ... mas em um subshell

    ( source runit.sh )
    
  3. Tente encontrar o alias / função atual de module com type module e, em seguida, modifique seu script. Observe que algumas variáveis de ambiente podem não estar definidas para module .
    Se você quiser, pode encontrar os scripts de inicialização no diretório $MODULESHOME/init/<shell> .

Comentário
Conforme lembrado no Q & A dos módulos

A child process (script) can not change the parent process environment. A module load in a script only affects the environment for the script itself. The only way you can have a script change the current environment is to source the script which reads it into the current process.

Então se você quiser evitar modificar o ambiente atual, eu acho que é melhor tentar mudar o shebang (1) ou fonte o script em um subshell (2). Eu não tenho certeza da usabilidade do case (3).

Nota
Trechos das páginas de manual e descrição dos módulos

module is a user interface to the Modules package. The module alias or function executes the modulecmd program and has the shell evaluate the command's output. The first argument to modulecmd specifies the type of shell.

The Modules package and the module command are initialized when a shell-specific initialization script is sourced into the shell. The script creates the module command, either as an alias or shell function, creates Modules environment variables

    
por 07.04.2015 / 21:42