1

I can source bash script (without shebang) easy as bash command in terminal but trying to do the same via python command

sourcevars = "cd /etc/openvpn/easy-rsa && . ./vars"
runSourcevars = subprocess.Popen(sourcevars, shell = True)

or

sourcevars = [". /etc/openvpn/easy-rsa/vars"]
runSourcevars = subprocess.Popen(sourcevars, shell = True)

I receive :

Please source the vars script first (i.e. "source ./vars") Make sure you have edited it to reflect your configuration.

What's the matter, how to do it correctly?I've read some topics here,e.g here but could not solve my problem using given advices. Please explain with examples.

UPDATED:

# os.chdir = ('/etc/openvpn/easy-rsa')
initvars = "cd /etc/openvpn/easy-rsa && . ./vars && ./easy-rsa ..."


# initvars = "cd /etc/openvpn/easy-rsa && . ./vars"
# initvars = [". /etc/openvpn/easy-rsa/vars"]
cleanall = ["/etc/openvpn/easy-rsa/clean-all"]
# buildca  = ["printf '\n\n\n\n\n\n\n\n\n' | /etc/openvpn/easy-rsa/build-ca"]
# buildkey = ["printf '\n\n\n\n\n\n\n\n\n\nyes\n ' | /etc/openvpn/easy-rsa/build-key AAAAAA"]
# buildca  = "cd /etc/openvpn/easy-rsa && printf '\n\n\n\n\n\n\n\n\n' | ./build-ca"
runInitvars = subprocess.Popen(cmd, shell = True)
# runInitvars = subprocess.Popen(initvars,stdout=subprocess.PIPE, shell = True, executable="/bin/bash")
runCleanall = subprocess.Popen(cleanall , shell=True)

# runBuildca = subprocess.Popen(buildca , shell=True)
# runBuildca.communicate()
# runBuildKey = subprocess.Popen(buildkey, shell=True )

UPDATE 2

buildca  = ["printf '\n\n\n\n\n\n\n\n\n' | /etc/openvpn/easy-rsa/build-ca"]
runcommands = subprocess.Popen(initvars+cleanall+buildca, shell = True)
7
  • You get that error from those snippets or from some other call after that? Because those should work fine but will only be in effect for that one shell instance and will not affect later shell instances or the running python script/environment. Commented Jan 13, 2016 at 20:21
  • Generally I need to run set of commands where shown is the first one and get this error from very beginning Commented Jan 13, 2016 at 20:28
  • You need to run all the commands in just one subprocess.Popen instance, since they're scoped to a single shell. Commented Jan 13, 2016 at 21:20
  • BTW, spaces should be used around =s in assignments, but not argument lists. See python.org/dev/peps/pep-0008/#other-recommendations Commented Jan 13, 2016 at 21:24
  • Your example shown (and thank you for editing it in) doesn't do as I recommended, contrary claim notwithstanding: It's still running your cleanall command in a separate shell from where you ran initvars. Commented Jan 13, 2016 at 21:34

1 Answer 1

4

There's absolutely nothing wrong with this in and of itself:

# What you're already doing -- this is actually fine!
sourcevars = "cd /etc/openvpn/easy-rsa && . ./vars"
runSourcevars = subprocess.Popen(sourcevars, shell=True)

# ...*however*, it won't have any effect at all on this:
runOther = subprocess.Popen('./easy-rsa build-key yadda yadda', shell=True)

However, if you subsequently try to run a second subprocess.Popen(..., shell=True) command, you'll see that it doesn't have any of the variables set by sourcing that configuration.

This is entirely normal and expected behavior: The entire point of using source is to modify the state of the active shell; each time you create a new Popen object with shell=True, it's starting a new shell -- their state isn't carried over.

Thus, combine into a single call:

prefix = "cd /etc/openvpn/easy-rsa && . ./vars && "
cmd = "/etc/openvpn/easy-rsa/clean-all"
runCmd = subprocess.Popen(prefix + cmd, shell=True)

...such that you're using the results of sourcing the script in the same shell invocation as that in which you actually source the script.


Alternately (and this is what I'd do), require your Python script to be invoked by a shell which already has the necessary variables in its environment. Thus:

# ask your users to do this
set -a; . ./vars; ./yourPythonScript

...and you can error out if people don't do so very easy:

import os, sys
if not 'EASY_RSA' in os.environ:
    print >>sys.stderr, "ERROR: Source vars before running this script"
    sys.exit(1)
Sign up to request clarification or add additional context in comments.

9 Comments

I have done like you recommend early and did it now but still get same error(
easy-rsa ... was meant to be a placeholder for you to replace with your clean-all script or such. I thought this was obvious from the context.
Thank you very much for your detailed explanation! seems combined command (prefix + cmd) works and at last I didn't get error but how to attach next command with user prompt to press enter? If I simply add it to statement via "+" it doesn't work!
You'll need to show the exact command. If you were using the mechanisms I suggested in your prior question to avoid any prompting, this would be moot. :)
You can't use + to join them directly like that because there's no && between cleanall and buildca. That's why I suggested an approach that would automatically add those separators in my comment on the question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.