1

I'm trying to run vnc server, but in order to do it first I need to run 'module load vnc'.

If I call which module in loaded bash shell then the command in not found is the PATH but in the same time it's available. It looks like the command is built-in.

In other words it looks like I need to execute two commands at once module load vnc;vncserver :8080 -localhost and I'm writing script to start it from python. I have tried different variants with subprocess.Popen like

subprocess.Popen('module load vnc;vncserver :8080 -localhost', shell=True) 

which returns 127 exit code or command not found.

subprocess.Popen('module load vnc;vncserver :8080 -localhost', shell=False)

showing

File <path>/subprocess.py line 621, in \__init__    
                                   errread, errwrite)
OSError: [Errno 2] No such file or directory.

If I specify shell=True, it executes from /bin/sh but I need it from /bin/bash.

Specifying executable='/bin/bash' doesn't help as it loads new bash shell but it starts as string but not as process, i.e. I see in ps list exactly the same command I would like to start.

Would you please advise how to do start this command from subprocess module? Is it possible to have it started with shell=False?

i alarmed alien
  • 9,412
  • 3
  • 27
  • 40
yart
  • 7,515
  • 12
  • 37
  • 37
  • 1
    Does `module load vnc` need to be run in the same shell / command as `vncserver`? Why do you need `/bin/bash`? `/bin/sh` is almost certainly a symlink to `/bin/bash`. – agf Aug 19 '11 at 14:43
  • You need a shell in order to execute multiple commands. You can try something like `'bash -c "module load vnc; vncserver :8080 -localhost"'` but it's probably not really the right way to do it. – tripleee Aug 19 '11 at 14:48
  • @tripleee that's what the `shell` and `executable` arguments he's talking about do – agf Aug 19 '11 at 14:49
  • @agf yes but if he needs the same bash he can use shell=false and use bash -c '...' as the single command to run. – tripleee Aug 19 '11 at 14:55
  • @agf, yes, it should be run in the same shell. You are right, /bin/sh is symlink to bash. I think then it shouldn't be the difference. – yart Aug 19 '11 at 15:11
  • Did you try `subprocess.Popen('bash -c "module load vnc; vncserver :8080 -localhost"')`? – agf Aug 19 '11 at 15:14
  • @triplee, I have tried this command `subprocess.Popen("/bin/bash -c 'module load vnc;vncserver :8080 -localhost'", shell=True)`. In result it shows `/bin/bash: module: command not found`. If you specify in the same command shell=False then appears `OSError: [Errno 2] No such file or directory.` message. – yart Aug 19 '11 at 15:16
  • @yart : maybe the path to your `module` command is only set in a your .bashrc file, and it may be not loaded by Popen. – Cédric Julien Aug 19 '11 at 15:18
  • @eryksun, thank you but there is no such file as `/etc/profile.d/modules.sh` – yart Aug 19 '11 at 15:29
  • @eryksun, there are no such files in both locations you have specified. – yart Aug 19 '11 at 15:38
  • The proper replacement for ‘which‘ is called ‘type‘. What does ‘type -all module‘ print for you? – tripleee Aug 19 '11 at 15:40
  • @triplee, thank you. It shows module function with the content similar to what eryksun wrote about the file. Eval command calls /modules.tcl file. – yart Aug 19 '11 at 15:50
  • @eryksun, there is such variable but there is no bash in init directory. There is $modules_shell variable which is bash. – yart Aug 19 '11 at 15:57
  • @eryksun, I just tried and at least it shows module help command which means syntax should be checked. – yart Aug 19 '11 at 16:09
  • @yart I am struck some where like here.. i have to load clearcase module using module load clearcase and then i need to execute clearcase commands using cleartool.. but i ve encountered the same problem. Did you solve your problem now ? If yes can you tell me ? – Sravan K Ghantasala Dec 07 '13 at 06:01
  • @SravanKGhantasala, have you tried the code from accepted answer? – yart Dec 09 '13 at 14:20
  • Yes, a failed attempt yart.. But thats ok i m directly adding path of clearcase to my system path and using it.. :P a way around can say... :) – Sravan K Ghantasala Dec 10 '13 at 02:33

3 Answers3

2

Environment Modules usually just modifies a couple environment variables for you. It's usually possible to skip the module load whatever step altogether and just not depend on those modules. I recommend

subprocess.Popen(['/possibly/path/to/vncserver', ':8080', '-localhost'], 
                 env={'WHATEVER': 'you', 'MAY': 'need'})

instead of loading the module at all.

If you do insist on using this basic method, then you want to start bash yourself with Popen(['bash',....

Mike Graham
  • 73,987
  • 14
  • 101
  • 130
  • thank you, Mike. I was also thinking directly to to start vncserver but I couldn't find where vncserver file is and it's unknown how environment is extended after specifying vnc module. – yart Aug 19 '11 at 15:44
  • @yart, In that case `Popen(["bash", "-c", "module load vnc; vncserver :8080 -localhost"])` or whatever might be your best bet. – Mike Graham Aug 19 '11 at 16:47
  • Mike, thank you. This command returns 127 exit code, but if I specify "-ci" instead of just "-c" it works. Why it works with interactive shell only? – yart Aug 22 '11 at 09:30
  • 1
    @yart, it's possible that the code to define the `module` builtin is in `bashrc` rather than `bash_profile`/`profile`, so `module` was never defined in a non-interactive session. Personally, I usually have my personal `~/.bash_profile` execute my `~/.bashrc`. – Mike Graham Aug 22 '11 at 13:16
0

You can call module from a Python script. The module command is provided by the environment-modules software, which also provides a python.py initialization script.

Evaluating this script in a Python script enables the module python function. If environment-modules is installed in /usr/share/Modules, you can find this script at /usr/share/Modules/init/python.py.

Following code enables module python function:

import os
exec(open('/usr/share/Modules/init/python.py').read())

Thereafter you can load your module and start your application:

module('load', 'vnc')
subprocess.Popen(['vncserver', ':8080', '-localhost'])
0

If you want to do it with shell=False, just split this into two Popen calls.

subprocess.check_call('module load vnc'.split())
subprocess.Popen('vncserver :8080 -localhost'.split())
Mike Graham
  • 73,987
  • 14
  • 101
  • 130
Ross Patterson
  • 5,702
  • 20
  • 38