How to source workspace in python script - python

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.

Related

How to run "source" command from python?

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

Shell command from Python "env: node: No such file or directory"

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?

Linux, Python open terminal run global python command

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.

Shell script not executing a python file

I am trying to run a script which in turn should execute a basic python script.
This is the shell script:
#!usr/bin/bash
mv ~/Desktop/source/movable.py ~/Desktop/dest
cd ~/Desktop/dest
pwd
ls -lah
chmod +x movable.py
python movable.py
echo "Just ran a python file from a shell script"
This is the python script:
#!usr/bin/python
import os
print("movable transfered to dest")
os.system("pwd")
os.system("mv ~/Desktop/dest/movable.py ~/Desktop/source")
print("movable transfered to dest")
os.system("cd ~/Desktop/source")
os.system("pwd")
Q1. The shell script is not executing the python file. What am I doing wrong?
Q2. Do I need to write the first line #!usr/bin/python in the python script?
Thank you.
You are missing a '/' in the shebang line:
#!usr/bin/python
should be
#!/usr/bin/python
Another thing I noticed was, you are calling cd in os.system. Since that command would be executed in a sub shell, it won't change the current directory of the calling script process.

How to execute a system command from a python file

I am using python and trying to execute a system command as below
code.py
import commands
import os
os.system('updatedb')
result:
sh-4.2$ python code.py
updatedb: can not open a temporary file for `/var/lib/mlocate/mlocate.db'
So how to execute all the system commands like above from a python module ?
This is almost certainly simply a permissions problem.
If you can trust your script to run as root:
$ sudo python code.py

Categories