Pass Python3 variable to C Shell Script - python

I did hours on research regarding the following question but I wasn't able to find an answer at all. Though there seem to be many fellows having problems with that. I hope I will recieve some help from the community. ;)
I have a Cshell script where I need to call a Python3 script from. Also I am passing a variable.
.csh
#!/bin/csh -f
set variable = value
/../geos.py $variable
So far so fine. In my Python3 script I take this variable, do some calculations and now want to pass back the 'new_variable' to the VERY SAME C shell script in order to proceed my set of data.
.py
import os
...
new_variable = 'foobar'
os.environ['new_variable'] = new_variable
return new_variable
My actual goal is that my C Shell script:
#!/bin/csh -f
set variable = value
/../geos.py $variable
echo $new_variable
doesn't return 'Undefined variable'. So obviously my code doesn't work. Sure, I might be able to temporarily save the python calculations into a file but this seems quite unconvincingly. Also, I understand that it is just not possible to manipulate an environmental variable of the shell through a child process, but still I only want to pass a normal variable. There should be one way, no?
If it is possible, I wasn't able to figure out any solution using subprocess.check_call. What am I missing?
E D I T:
Merci beaucoup.
I knew that there must have been an easy solution. Thanks a lot!
For CSHELL the following code worked:
set new_variable=`../geos.py $variable`
echo $new_variable
For BASH the following code worked:
new_variable=`../geos.py $variable`
echo $new_variable
In the python script itself you don't need to do anything but putting your desired variable into standard output, e.g. print(you_even_can_name_them_as_you_want). No os.environ oo whatever necessary. Made my day. SOLVED

in bash I'd use:
new_variable=$(../geos.py $variable)
Have the python script produce the new value as standard out (i.e. print(new_variable) )
In csh I don't know, maybe you would have to use backquotes instead of $() ?

Related

Storing python script return value to bash shell in a jenkins job

I have a python script a.py that returns a tuple of two values.
I am running this script from a Jenkins bash shell and I need to be able to retrieve the return values and use them in the further steps of the job.
As of now, the call to the script looks like:
ret_tuple=($($ENV_PATH/bin/python a.py))
Then I am trying to access the return value and assign it to variables that later I would inject into the Jenkins job
echo "${ret_tuple[0]}"
echo "${ret_tuple[1]}"
echo SRC_BUCKET=${ret_tuple[0]} > variables.properties
echo DST_BUCKET=${ret_tuple[1]} > variables.properties
Later, I forward these variables into another job that this job triggers and I can see that the parameters that are being sent from the variables are incorrect.
One of them holds $SRC_BUCKET and the second one Disabled! (which doesn't make a lot of sense to me).
I pass the variables like that:
data_path=${SRC_BUCKET}
destination_path=${DST_BUCKET}
Am I doing this in the right way and I should look for the problem in another place? or there's something wrong with this variable assignment above?
EDIT:
The python script returns two strings
src_bucket_path = os.path.join(export_path, file_name)
dst_bucket_path = os.path.join(destination_path, dst_bucket_suffix_path)
return src_bucket_path, dst_bucket_path
Maybe use command expansion, so the command is evaluated before outputted into the variables.properties files.
$(echo SRC_BUCKET=${ret_tuple[0]} > variables.properties)
$(echo DST_BUCKET=${ret_tuple[1]} > variables.properties)
A good article for you to read,
http://www.compciv.org/topics/bash/variables-and-substitution/
If you run your scripts in the same shell session window, you could create an environment variable from one script, and then when you run the next script you can access the environment variable.

Send and recieve variable from subprocess

This may be a very simple question, but I'm new to python and haven't been able to figure it out.
I want to do something very simple: call a subprocess and send to it two variables at the start (eg: G=[0,1] and K=3), that it needs to run. From the subprocess I want to receive back a list of values in my original script.
I manage to get it to run without any problems:
os.system('abaqus cae noGUI=E11_1')
...but the sending and receiving values I can not figure out. Can anyone give me a suggestion?
I solved my problem.
For anyone seeing this and also working on abaqus like me. To get interact with an abaqus script you need to use the "abaqus python" module (instead of "abaqus CAE"). By coding like this:
os.system('abaqus python script.py var1 var2')
you will send var1 and var2 (as string) to script.py. There you can access the variables with
v1 = int(sys.argv[1]) (= var1)
v2 = int(sys.argv[2]) (= var2)
In the python.py script you can access an .odb with:
odb = openOdb(path+odbname+'.odb')
and do whichever operations you want.
I hope this helps anyone who has the same problem.

How to access Bash environment variable in Python using subprocess?

I can determine the width of the terminal in Python with a subprocess-handled query such as the following:
int(subprocess.Popen(['tput', 'cols'], stdout = subprocess.PIPE).communicate()[0].strip('\n'))
How could I determine the Bash user name in a similar way? So, how could I see the value of ${USER} in Python using subprocess?
As Wooble and dano say, don't use subprocess for this. Use os.getenv("USER") or os.environ["USER"].
If you really want to use subprocess then Popen(['bash', '-c', 'echo "$USER"'], ...) seems to work as does Popen("echo $USER", shell=True) though neither of those is particularly pleasant (though to use environment variables on the command line being executed the shell must be involved so you can't really avoid it).
Edit: My previous subprocess suggestion did not seem to work correctly. I believe my original test was flawed.

Passing variable from bash-python-bash

To use logarithmic function, I used export to pass a variable $var1 from bash to python script. After the calculation, I used
os.environ['var1']=str(result)
to send the result back to bash script.
However, the bash still shows the unmodified value.
You can have a look at the os.putenv(key, value) function here maybe it could help you.
Although as noted on the doc :
When putenv() is supported, assignments to items in os.environ are automatically translated into corresponding calls to putenv(); however, calls to putenv() don’t update os.environ, so it is actually preferable to assign to items of os.environ.
EDIT :
moooeeeep thought about it just a minute before me, but the variable you change only applies to the current process. In such a case I can see two solutions :
- Write the data to a file and read it with your bash script
- Call your bash script directly from within python so that the bash process would inherit your modified variable.

Running a bash file with Python

I've got a bash file that I normally execute using Cygwin.
I need to run this file from my Python code.
I tried this:
for bashfile in files:
p = Popen(bashfile, cwd=dname) #dname is the current directory of the script
stdout, stderr = p.communicate()
I've also seen a similar question here, but when trying to run it that way it says that it can't find the directory of my bash file...
Any ideas? Thanks! :-)
Edit: bashfile has a full path.
Do you need its output to get it directly to Python? If not this may be very fast and easy solution:
os.system("""here some code you use to execute in Terminal""")
You can also try this, though it does (and will no matter what you try) matter where the directory is. This, as far as the output goes, may be a little bit cleaner than the os method.
import commands
cmd="bash ./script.sh"
commands.getoutput(cmd)
If the case is that you need to change the directory:
cmd = "/path/to/your/script/script.sh"
The added benefit of using this method, versus say, os is that you can assign the output to a variable...
fun_times = commands.getoutput("bash ./script.sh")
whereas...
not_fun_times = os.system("./script.sh")
will throw an error.
etc, etc.

Categories