I need to set up the ROS2 Galactic environment by sourcing the following file through python: -
"source /opt/ros/galactic/setup.bash"
If I write the above line in terminal it will be sourced but I need to do this from python script.
I tried: -
import subprocess
subprocess.call("source /opt/ros/galactic/setup.bash", shell=True)
and
import os
os.system('source /opt/ros/galactic/setup.bash')
But none of them is sourcing the enviornment. I am working on Ubuntu 20.04, Python 3.8.10.
This will not impact your Python runtime environment. subprocess starts a shell wherein it runs your script (setup.bash) and then terminates.
Consider this:
import subprocess
import os
subprocess.run('export FOO=1', shell=True)
print(os.environ['FOO'])
This tries to set an environment variable in the sub-shell. That actually works but when run() returns, the shell no longer exists. Thus, when we try to access the environment variable we get KeyError
Related
I got a Node.js CLI program called meyda installed (Mac OS 10.14) using:
sudo npm install --global meyda
From the Terminal I can call the program and it works as expected; like:
meyda --bs=256 --o=apagodis2.csv DczN6842.wav rms
Now, I want to call it from inside a python script (using Spyder) at the same location and tried this – but getting error:
import os
os.system ('/usr/local/bin/meyda --bs=256 --o=apagodis4.csv samples_training/DczN6842.wav rms')
>>> env: node: No such file or directory
I can issue more "traditional" shell commands like this from the same Python script and it works:
os.system ('cp samples_training/DczN6842.wav copy.wav')
Also tried subprocess call with same result. I confirmed the executable is at /usr/local/bin/
To make sure I also removed all file arguments calling the program using only the help flag but same, error.
os.system ('/usr/local/bin/meyda -h')
>>> env: node: No such file or directory
Why is the command not found from inside Python but sucessfully in the macOS Terminal?
My django project fetches credentials from environment variables, now I want to automate this process and store the credentials in the vault(hashivcorp).
I have a python and shell script which fetches data from an API and exports it as environment variables, when I run it using os.system command it runs the shell script but as it runs it in a subprocess, I can't access the variables in the main(parent) process/shell. Only way of doing it by inserting the shell script in the settings.py file.
Is there any way I can do it so that I get those in the main process?
P.s: I did try sourcing, os.system didn't recognise it as a command.
Here's the code I'm running:
import os
os.environ['ENV'] = 'Demo'
os.system('python3 /home/rishabh/export.py')
print(os.environ.get('RDS_DB_NAME'))
output:
None
the python file, shell script works just fine.
One way to do it is to run export.py in the same process, as user1934428 suggested:
import os
import sys
os.environ['ENV'] = 'Demo'
sys.path.append('/home/rishabh/')
import export # runs export.py in the same process
print(os.environ.get('RDS_DB_NAME'))
This assumes there are no __name__ == '__main__' checks inside export.py.
You only need the sys.path line if export.py is in a different directory than your current script.
I am using a python script in order to run four different python scripts that each execute a command, the purpose of this is to run the main python script on startup. This is what is inside the main python script:
#!/usr/bin/env/python
import os
os.system('x-terminal-emulator -e python ./one.py')
os.system('x-terminal-emulator -e python ./two.py')
os.system('x-terminal-emulator -e python ./three.py')
os.system('x-terminal-emulator -e python ./four.py')
When I run it, it does create four terminals and executes each of the .py in each terminal, but the one.py, two.py, and three.py return an error of "sh: 1: source: not found". I know this is because I am using these lines:
os.system('cd /home/nvidia/catkin_ws')
os.system('source devel/setup.bash')
Sourcing is needed in order the commands after it, how do I fix this problem? I am using ROS Kinetic with Linux Ubuntu 16.04.
Content of one.py
#!/bin/bash
import os
os.system('cd /home/nvidia/catkin_ws')
os.system('source devel/setup.bash')
os.system('roslaunch pocketsphinx continuous.launch spdict:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/speaker_test.dic spkws:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/speaker_test.kwlist sphmm:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/speaker_verification/an4.ci_cont_adapt/ dict:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/keywords_spk_verification.dic kws:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/keywords_spk_verification.kwlist gram:=/home/nvidia/catkin_ws/src/pocketsphinx/demo/asr_spk grammar:=asr rule:=rule sp_verif:=false')
Content of two.py
#!/bin/bash
import os
os.system('cd /home/nvidia/catkin_ws')
os.system('source devel/setup.bash')
os.system('rosrun pocketsphinx execute_commands.py')
Content of three.py
#!/bin/bash
import os
os.system('cd ~/catkin_astra')
os.system('source devel/setup.bash')
os.system('roslaunch astra_launch astra.launch')
os.system() starts a new shell, executes whatever you pass it and then closes the shell down again. Subsequently created shells are not affected by any changes to that shell, like changing the working directory or sourcing stuff.
I have been trying to use the sub-process module to run a sequence of shell commands in succession, to automate certain tasks using python(for the first time). The following are the steps involved in the task mentioned before:
Goto location 1
Execute the cshell script in the path location
Goto location 2
Execute another cshell script in the new path location
I have written the following code for the purpose:
#! /usr/bin/python
import subprocess
import os
path = r'/AA/BB/CC/DD/EE/FF/GG/HH/'
os.chdir(path)
p1 = subprocess.Popen('./xyz.csh', stdout=subprocess.PIPE, shell=True)
outdata = p1.communicate()[0]
os.chdir('../XX/YY/')
subprocess.call("./abc.csh")
print("Simulation complete")
The script file contains a few setenv commands which set the environment variables that are required for the execution of abc.csh script.
I have the following query about the usage of subprocess.Popen() routine, as the subprocess.Popen() routine creates a sub-shell for the execution of xyz.csh, the environment variables set by the execution of the script vanish once the execution is completed, and abc .csh (which requires those environment variables for execution) throws errors during execution. Is there a way to set environment variables in main shell so that abc.csh can be executed with fail.
Not sure if this is possible. I have a set of python scripts and have modified the linux PATH in ~/.bashrc so that whenever I open a terminal, the python scripts are available to run as a command.
export PATH=$PATH:/home/user/pythonlib/
my_command.py resides in the above path.
I can run my_command.py (args) from anywhere in terminal and it will run the python scripts.
I'd like to control this functionality from a different python script as this will be the quickest solution to automating my processing routines. So I need it to open a terminal and run my_command.py (args) from within the python script I'm working on.
I have tried subprocess:
import subprocess
test = subprocess.Popen(["my_command.py"], stdout=subprocess.PIPE)
output = test.communicate()[0]
While my_command.py is typically available in any terminal I launch, here I have no access to it, returns file not found.
I can start a new terminal using os then type in my_command.py, and it works
os.system("x-terminal-emulator -e /bin/bash")
So, is there a way to get the second method to accept a script you want to run from python with args?
Ubuntu 16
Thanks :)
Popen does not load the system PATH for the session you create in a python script. You have to modify the PATH in the session to include the directory to your project like so:
someterminalcommand = "my_command.py (args)"
my_env = os.environ.copy()
my_env["PATH"] = "/home/usr/mypythonlib/:" + my_env["PATH"]
combine = subprocess.Popen(shlex.split(someterminalcommand), env=my_env)
combine.wait()
This allows me to run my "my_command.py" file from a different python session just like I had a terminal window open.
If you're using Gnome, the gnome-terminal command is rather useful in this situation.
As an example of very basic usage, the following code will spawn a terminal, and run a Python REPL in it:
import subprocess
subprocess.Popen(["gnome-terminal", "-e", "python"])
Now, if you want to run a specific script, you will need to concatenate its path with python, for the last element of that list it the line that will be executed in the new terminal.
For instance:
subprocess.Popen(["gnome-terminal", "-e", "python my_script.py"])
If your script is executable, you can omit python:
subprocess.Popen(["gnome-terminal", "-e", "my_script.py"])
If you want to pass parameters to your script, simply add them to the python command:
subprocess.Popen(["gnome-terminal", "-e", "python my_script.py var1 var2"])
Note that if you want to run your script with a particular version of Python, you should specify it, by explicitly calling "python2" or "python3".
A small example:
# my_script.py
import sys
print(sys.argv)
input()
# main.py
import subprocess
subprocess.Popen(["gnome-terminal", "-e", "python3 my_script.py hello world"])
Running python3 main.py will spawn a new terminal, with ['my_script.py', 'hello', 'world'] printed, and waited for an input.