Exporting variables from Shell script and accessing it in Python script - python

I am trying to export a variable from my shell script and then access it from my python script.
#!/bin/bash
test="hello, python!!!"
export test
python test.py
My Python script is as follows:
#!/usr/bin/python
import os
text = os.environ.get("test")
print(text)
After I source my shell script I dont see the printed output on command line. Instead, I see:
shell_script:export:3: not valid in this context: test^M
But if I individually echo or run the python script after sourcing the shell script, I am able to get the desired result. Any ideas on how to do it in one go??

Related

Run terminal script in python?

I am using python and I am trying to run a shell script that is located in another folder I am trying
subprocess.call(['source','../Apps/appName/run'])
Where 'run' is a shell script I wrote and made an executable. But it keeps giving errors such as
No such file or directory or **No such file or directory: "source"
I have also tried the following
subprocess.call(['source','../Apps/appName/run'])
subprocess.call(['source ../Apps/appName/run'])
subprocess.call(['.','../Apps/appName/run'])
I am trying to run the script and leave it alone (as in I do not want any return value or to see what the output of the shell script is.
Thank you in advance
source is a shell builtin that reads a file and interprets the commands in the current shell instance. It's similar to C #include or Python import. You should not be using it to run shell scripts.
The correct way to run a script is to add a shebang like #!/bin/bash to the first line, and chmod +x yourscriptfile. The OS will then consider it a real executable, which can be executed robustly from any context. In Python, you would do:
subprocess.call(['../Apps/appName/run'])
If for whichever reason this is not an option, you can instead explicitly invoke bash on the file, since this is similar to what would happen if you're in bash and type source:
subprocess.call(['bash', '../Apps/appName/run'])

Is there a way to get the output of a bash script to "feed" into a variable in a python script that executes the action initially?

So, I have a bash script that feeds out data from a sensor that is connected to the NVidea Jetson TK-1 in string format in the shell. Is there any way I can run a python script that initializes the bash script. Takes the output data in bash, feeds it back into a python string variable where it can be parsed? I cannot edit the bash script.
Thanks
In python:
import subprocess
bash_output = subprocess.check_output('run bash script here')
Subprocess.check_output sends commands to the shell and the shell pipes the results back to python. Look at examples of using and documentation on subprocess.check_output here.

Executing a python script when a terminal is opened within that terminal

Im interested if there is a way to run a python script when you open a terminal window. For example
print "hello world"
Every time i open a terminal, hello world would appear.
If you are using bash, anything you put in your ~/.bashrc file will be run when you open the terminal, i.e.
python my_script.py
will execute the script my_script.py.
Every time i open a terminal, hello world would appear.
Just do:
clrscr("Hello World") # or whatever string you want
anywhere in any of your python scripts.
To achieve this effect, you have to do the following 2 things
1- For sake of portability you have to make a small module as shown below-
# goodManners.py
from os import system as command # for calling to system's terminal
from platform import system as osName # for getting the OS's name
def clrscr(text):
if osName()=='Windows':
command('cls')
else:
command('clear')
print(text)
2- Now in your ~/.bashrc:
export PYTHONSTARTUP=$HOME/.pythonstartup
and put your python code in $HOME/.pythonstartup, like:
from goodManners import clrscr

How to execute a python script and leave open a shell for further testing in VIM

When I write python script in VIM I would like to test them into VIM directly I know that I can use:
w !python -
But this execute the script and suddenly close the shell so if I want to test a function I can't call it with various arguments!
For example if I have this code:
print "How can I test the following function in Vim?"
def testfunc(test):
print test*2
When I run in VIM w !python - it print me the print statement but I can't try to test the function with some arbitrary arguments. How can I run the script in a python shell for further testing?
You can run a Python script and then immediately switch to interactive mode with the -i flag:
python -i test.py
You may run interactive buffer like Conque Term with python commandline and then just import your .py file in it.

Python 'source HOME/.bashrc' with os.system()

I am writing a python script (Linux) that is adding some shell aliases (writes them to HOME/.bash_aliases).
In order to make an alias available immediately after it was written I should issue the following bash built-in:
source HOME/.bashrc
source is a bash built-in so I cannot just:
os.system(source HOME/.bashrc)
If i try something like:
os.system('/bin/bash -c source HOME/.bashrc')
...will freeze the script (just like is waiting for something).
Any suggestions ?
What you want is not possible. A program (your script) cannot modify the environment of the caller (the shell you run it from).
Another approach which would allow you to do something close is to write it in terms of a bash function, which is run in the same process and can modify the caller. Note that sourcing during runtime can have possible negative side-effects depending on what the user has in their bashrc.
what you are trying to do is impossible. or better: how you are trying to do it is impossible.
your bash command is wrong. bash -s command does not execute command. it just stores the string "command" in the variable $1 and then drops you to the prompt. that is why the python script seems to freeze. what you meant to do is bash -c command.
why do you source .bashrc? would it not be enough to just source .bash_aliases?
even if you got your bash command right, the changes will only take effect in the bash session started from python. once that bash session is closed, and your python script is done, you are back at your original bash session. all changes in the bash session started from python is lost.
everytime you want to change something in the current bash session, you have to do it from inside the current bash session. most of the commands you run from bash (system commands, python scripts, even bash scripts) will spawn another process, and everything you do in that other process will not affect your first bash session.
source is a bash builtin which allows you to execute commands inside the currently running bash session, instead of spawning another process and running the commands there. defining a bash function is another way to execute commands inside the currently running bash session.
see this answer for more information about sourcing and executing.
what you can do to achieve what you want
modify your python script to just do the changes necessary to .bash_aliases.
prepare a bash script to run your python script and then source .bash_aliases.
#i am a bash script, but you have to source me, do not execute me.
modify_bash_aliases.py "$#"
source ~/.bash_aliases
add an alias to your .bashrc to source that script
alias add_alias='source modify_bash_aliases.sh'
now when you type add_alias some_alias in your bash prompt it will be replaced with source modify_bash_aliases.sh and then executed. since source is a bash builtin, the commands inside the script will be executed inside the currently running bash session. the python script will still run in another process, but the subsequent source command will run inside your currently running bash session.
another way
modify your python script to just do the changes necessary to .bash_aliases.
prepare a bash function to run your python script and then source .bash_aliases.
add_alias() {
modify_bash_aliases.py "$#"
source ~/.bash_aliases
}
now you can call the function like this: add_alias some_alias
I had an interesting issue where I needed to source an RC file to get the correct output in my python script.
I eventually used this inside my function to bring over the same variables from the bash file I needed to source. Be sure to have os imported.
with open('overcloudrc') as data:
lines = data.readlines()
for line in lines:
var = line.split(' ')[1].split('=')[0].strip()
val = line.split(' ')[1].split('=')[1].strip()
os.environ[var] = val
Working solution from Can I use an alias to execute a program from a python script :
import subprocess
sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"])
sp.communicate()

Categories