Python GUI to execute Bash/ksh environment and shell applications? Python GUI to execute Bash/ksh environment and shell applications? shell shell

Python GUI to execute Bash/ksh environment and shell applications?


As I understand your question, you're trying to execute an external command with one of n sets of environment variables, where n is specified by the user. The fact that it's a GUI application doesn't seem relevant to the problem. Please correct me if I'm missing something.

You have several choices:

Execute a command in Python with custom environment variables

Rather than store the environment variables in separate files, you can set them directly with the env argument to Popen():

If env is not None, it must be a mapping that defines the environment variables for the new process; these are used instead of inheriting the current process’ environment, which is the default behavior.

So instead of having app1.sh, app2.sh, app3.sh, and so on, store your environment variable sets in Python, and add them to the environment you pass to Popen(), like so:

env_vars = {  1: {    'DIR': '/some/location/',    'LICENSE': '/some/license/'    'SOMEVAR': 'some value'  },  2: ...}...environ_copy = dict(os.environ)environ_copy.update(env_vars[n])subprocess.Popen('external_application', shell=True, env=environ_copy, ...)

Modify the environment with a wrapper script

If your environment vars must live in separate, dedicated shell scripts something like your helper is the best you can do.

We can clean it up a little, though:

#!/usr/bin/env bashif source "$1"; then  # Set up env variables    external_app      # Runs the actual applicationelse    echo "Error executing $1" 2>/dev/stderr    exit 1            # Return a non-zero exit statusfi

This lets you pass app1.sh to the script, rather than create n separate helper files. It's not clear why you're using & to background the process - Popen starts a separate process which doesn't block the Python process from continuing. With subprocess.PIPE you can use Popen.communicate() to get back the process' stdout and stderr.

Avoid setting environment variables at all

If you have control of external_process (i.e. you wrote it, and can modify it), you'd be much better off changing it to use command line arguments, rather than environment variables. That way you could call:

subprocess.Popen('external_command', '/some/location/', '/some/license/', 'some value')

and avoid needing shell=True or a wrapper script entirely. If external_command expects a number of variables it might be better to use --flags (e.g. --dir /some/location/) rather than positional arguments. Most programming languages have a argument processing library (or several) to make this easy; Python provides argparse for this purpose.

Using command line arguments rather than environment variables will make external_process much more user friendly, especially for the use case you're describing. This is what I would suggest doing.