Sourcing bash file inside PyQt4 GUI - bash

I'm working on a GUI built with PyQt4 and Python 2.7 that launches various demos for a Clearpath Husky running ROS Indigo. The GUI switches between launching navigation demos and visualizing my physical robot. To do this, it has to switch between launching demos on a local ROS and the ROS on my Husky. When switching between the two different ROS instances I need to be able to "source" the devel/setup.bash for each OS so that the packages are built correctly and visualizing the Husky inside Rviz doesn't break (Errors with TF frames like "No tf data. Actual error: Fixed Frame [odom] does not exist" and with RobotModel "URDF Model failed to parse"). In my .bashrc, if I source the Husky's setup.bash, the visualization works fine until I try running a local demo. This also happens vice versa; while sourcing the local setup.bash will run the local demos just fine, the Husky's visualization breaks.
Is there a way to use python's subprocess (or another alternative) to source the appropriate devel/setup.bash within the GUI's instance so that the visualization won't break?

Yes, it should be sufficient to source the setup script just before executing the ROS command you want, for instance:
#!/usr/bin/env python
from subprocess import Popen, PIPE
shell_setup_script = "/some/path/to/workspace/devel/setup.sh"
command = "echo $ROS_PACKAGE_PATH"
cmd = ". %s; %s" % (shell_setup_script, command)
output = Popen(cmd, stdout=PIPE, shell=True).communicate()[0]
print(output)
As you see, shell=True is used, which will execute the cmd in a subshell. Then, cmd contains . <shell_setup_script>; <command> which sources the setup script before executing the command. Please note that the .sh file is sourced instead of .bash since generic POSIX shell is likely to be used by Popen.

Related

Bash Script can't access proper environment variables in GCP Instance

I have tried everything to execute a manually installed command in a bash script that normally executes fine in my user shell (yigit#instance-1). I'm thinking that GCP Instances can't access proper env variables.
The command that I've installed called Task Spooler and executed as ts in shell. I setup the tar package using Makefile in following paths (by make install):
ts is /usr/local/bin/ts
ts is /usr/bin/ts
ts is /bin/ts
So my shell script is as follows:
#!/bin/bash
echo $PATH
ts python3 somepyscript.py
By looking output of PATH env, it seems there isn't any mismatching of environment variables to access the command. However output comes to me as:
/home/yigit/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
./tm_pipeline.sh: line 10: ts: command not found
As said, the command works fine in my user shell that I connected over SSH. Can't understand why this is happening in VM Instance... I know GCP offers start-up scripts to VMs in settings and regarding containerization applications via Cloud Build etc. Could it be a problem about the interference with these or is there something I can do .. ? Thanks for any help in advance.

How to save a Python 2 idle/shell/command prompt interactive session on Windows?

I run calculations on Windows for hours and would like to have the calculation report/log inside the interactive IDLE/shell window be saved to a file at the end by a command.
Would be nice to exit() and close the window too.
As much as I like Linux, this is an Unattended Windows machine, hence, some modules/commands are not available, sadly, and the ability to install other software is limited.
The fact that the developers did not think of a command to save the transactions within the IDLE/shell is surprising.
I know in some environments you can direct the output of a job, like a report to another text file by using the key -o, --o, --output, > to a text file. Surprisingly Python does not support anything like that!
Any help would be appreciated
Thanks
Windows Command Prompt supports stdout redirection and probably stderr redirection. I just tested python -c "print(test)" > F:/dev/tem/out.txt and the print out went to out.txt. Replace -c "print('test') with script.py and the same should happen. Piping stdout of one program to stdin of another might work. You might be able to chain programs with a .bat file. PowerShell likely is more powerful and flexible, but I have never used it.
I am not completely clear on what you are asking, but I hope the following answers your questions.
Python runs in 2 modes: batch and interactive. Interactive mode is intended for ephermeral interaction with a human. Batch mode is for unattended computation, with occasional screen messages, but with most results sent to a file other than the screen. Both modes are combined when you run python -i xyz.py. The file is first run in batch mode, and then Python shifts to interactive mode.
It sounds like you should be using batch mode rather than either Python's or IDLE's interactive mode. If your code runs from IDLE, you should be able to run it directly with the same python.exe that you used to run IDLE. There are exceptions, of course, if one makes one's code dependent on running within IDLE, but this is unlikely to be an accident or to be needed for unattended running.
The IDLE Shell simulates interactive Python. When a file is run from an editor window, IDLE simulates python -i file-being-edited.py, with screen output going to Shell. In either case, an interactive user can save the contents of Shell with the File => Save As menu command. So there is such a command. There are also close window and exit commands and shortcuts.
In IDLE's intended use, as an interactive python learning and program development environment, there is no need from for a program to issue these commands. To save data in a file, a program can open a file and write data directly.
Try to see if you can install Jupyter Notebook (not separate software, but just a python module)
pip install jupyter
Jupyter notebook is highly helpful for saving and sharing your code. It can be used as both a shell and as a script editor.

How to execute a bash script from within my python project

I am writing some automation to control a simulator. I am also using WebDriverAgent along with openatx python bindings in pycharm. There are some things that are fast using cURL in a bash script and some methods that are stronger in the python solution. I want to use a mix of both. I have imported bashSupport into pycharm and would like to execute a bash script from within my file system of the project.
I have tried subprocess import and os but it doesn't seem to be executing my script. Here is an example:
import subprocess
subprocess.call(['launch_wda.sh'])
with device.session('com.apple.mobilesafari') as app:
print app.orientation
app(label="Address").tap()
app(label="Address").set_text("facebook.com \n")
the launch_wda.sh is in my file structure of the project. Is my syntax incorrect or am I missing something else?
Try these changes:
Add ./ before script name. As this could be some path related issue.
Try adding shell=True if you are not under Posix system and you do not have something like this #!/bin/sh as a first line of your bash script.
Last but not the least, check the permissions for the bash script.
Hope this helps.

Alias to Launch Python .py Script

I am trying to create an Alias to launch mystepper6.py and moveit.py and sudo ps ax by placing the following alias' in sudo nano ~/.bashrc (Note: I am using Python 2 for this script.)
reboot='sudo reboot'
ax='sudo ps ax'
runstepper='python home/pi/mystepper6.py'
moveit='sudo python home/pi/moveit.py'
The alias reboot works fine but none of the others work at all. All I get is "bash: runstepper: command not found".
I am doing this because I am trying to control my webcam on my Raspberry Pi 2 using my iPhone with the iFreeRDP app. I use remote desktop connection from my Windows 10 laptop. The problem with this app and some other similar apps, is that the period and space keys do not function (it is a know reported issue). This makes typing full commands impossible.
Incidentally, I tried to use the VNC Viewer iPhone app and got my Raspberry Pi 2 hijacked when I loaded the required software onto the RPi2 requiring me to get a new SD card. Fortunately, I just cloned my SD card a few hours prior. Long story, but I am very weary about using VNC Viewer now.
Please help me with my alias' so I can either type one word with no spaces or periods or create a desktop short cut that I can double click so I can use it as a workaround for the deficiencies of these otherwise good apps. I am not sure the Ctrl + C works on the app keyboards either, so a short cut for that would be good as well.
to create aliases in your shell, you shall use the alias shell directive:
alias reboot='sudo reboot'
alias ax='sudo ps ax'
To run ps ax you do not need to sudo first. If you're running a standard kernel, any user can see the list of all processes without special privileges.
For the two python aliases:
alias runstepper='python home/pi/mystepper6.py'
alias moveit='sudo python home/pi/moveit.py'
^-- missing / here
do not forget about the first / in the path, or whenever you launch the aliased command, you'll have python look up for the script relatively to the current directory. i.e. if you're in /home/pi, it will look it up into /home/pi/home/pi/movestepper6.py and tell you the script does not exists. So the proper command should be:
alias runstepper='python /home/pi/mystepper6.py'
alias moveit='sudo python /home/pi/moveit.py'
Though as a suggestion to you, instead of making aliases to run python scripts, I'd make them into a proper python package. Considering that within both codes your entry points are a function called main(), i.e., both scripts end with:
if __name__ == "__main__":
main()
you should create a directory for your project:
cd /home/pi
# create a directory for your python project:
mkdir motion_control
# create a directory to place your scripts within:
mkdir motion_control/motion_control
# adding an empty __init__.py file makes that directory a python package
touch motion_control/motion_control/__init__.py
nano motion_control/setup.py
and now you just have to add this within the setup.py file:
from setuptools import setup
setup(name='motion_control',
version='0.1',
description="Python library to operate stuff that move on my rasppi",
long_description='explain how to use the tools installed by this package',
classifiers=[],
keywords='raspberrypi motion control',
author='YOU',
author_email='YOUR#EMAIL',
url='ANY URL YOU THINK IS RELEVANT',
license='MIT', # or any license you think is relevant
packages=['motion_control'],
zip_safe=False,
install_requires=[
# add here any tool that you need to install via pip
# to have this package working
'setuptools',
],
entry_points="""
# -*- Entry points: -*-
[console_scripts]
runstepper = motion_control.mystepper6:main
moveit = motion_control.moveit:main
""",
)
the entry_points part is very important, as it's telling python where to look for the first function to execute to have the script run. For example:
moveit = motion_control.moveit:main
means "look for the main() function within the moveit module in the motion_control package". So adapt accordingly! As a note: don't make that main() function take any parameter, but rather do the argument parsing within it (if you parses arguments).
and finally, to install it, all you need to do is:
cd motion_control
sudo python setup.py install
and you'll have runstepper and moveit installed in the same directory as your python executable.
HTH

`gitk` program found using the `where` command but cannot be executed?

I'm trying to run gitk on Windows but the console gives me:
'gitk' is not recognized as an internal or external command,
operable program or batch file.
But then, I can do
> where gitk
C:\Program Files (x86)\Git\bin\gitk
How comes?
UPDATE: Stealing the OP's comment:
Thanks for a (lengthy) explanation, the easiest fix for me was to move from the old msysGit (1.9.5) version to the newer "Git for Windows" builds which has a proper Windows wrapper for gitk.
gitk, unlike most git commands, is a shell script that invokes Tcl.
If you examine the gitk executable file itself, its first few lines are:
#!/bin/sh
# Tcl ignores the next line -*- tcl -*- \
exec wish "$0" -- "$#"
(At least that's what it looks like on my Linux system; the Windows installer for gitk might change that.)
On a Unix-like system, that first line, known as a "shebang", tells the system to invoke /bin/sh to execute the file rather than executing it directly.
The third line executes the wish command, which executes the script as a Tcl script.
If you have Tcl installed on your Windows system, you should be able to run gitk as a Tcl script using something like this:
C:\> tclsh "C:\Program Files (x86)\Git\bin\gitk"
(Disclaimer: I have not tried this.)
You might also be able to change the command's name from gitk to gitk.tcl and set up a file association in Windows so it will be invoked correctly. (I'm a little surprised that the Windows git installer didn't do this for you.)
More information on running Tcl scripts on Windows can be found here.
And this question discusses invoking gitk on Windows from the context menu rather than from the command line.

Resources