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
Related
I am writing a command line tool in python and using pip to distribute it. I have written some scripts (one for bash and one for zsh) to allow the tool to have tab completion. Is there a way to get pip to install these scripts when someone does a pip install?
For example:
I have a completion.bash file. When someone does
pip install mypackage
It will also source the bash file.
I'm pretty sure I can do this for linux and bash by putting the script in my data_files section in the setup.py script.
data_file=[
('/etc/bash_completion.d', ['bin/completion.bash'])
],
But how can I do this so it is platform and shell independent? I need it to work for mac/linux in both bash and zsh. If possible, even support windows.
Is this possible? And if so, how?
In case it matters, here is my bash script:
_foo_complete() {
COMPREPLY=()
local words=( "${COMP_WORDS[#]}" )
local word="${COMP_WORDS[COMP_CWORD]}"
words=("${words[#]:1}")
local completions="$(foo completer --cmplt=\""${words[*]}"\")"
COMPREPLY=( $(compgen -W "$completions" -- "$word") )
}
complete -F _foo_complete foo
I am currently installing it by just running source completion.bash
You are asking several different questions.
First, there's no cross-platform or cross-shell solution for defining custom shell-completions. The one you posted works for bash, but in tcsh, for example, you use tcsh's complete command, which works differently than bash's.
Second, sourcing the files which contain those completion-definitions at the time of pip install wouldn't do much good. The completions might work in that very session, but what you probably want is for them to take effect in future sessions (i.e. shell invocations) as well. For that, your files would have to be sourced each time the shell starts (e.g. from within user's .bashrc, in case of bash).
This measn that "installing" your files simply means placing them somewhere, and suggesting the users should source them from their respective dot-rc file. Even if you could, you shouldn't try to "force" it. Give your users the option to add that to their dot-rc file if they want.
The best approach would probably be to include in your package a completion-definitions file per supported shell, e.g. complete.bash, complete.tcsh, and god knows what for windows (sorry, I'm not a windows user).
I'm both new here and with MacOS and coding.
I know in windows I can create bash file to have an executable command in cmd. I've researched and discovered I can use similar file with MacOS (shell files) but I'm struggling to understand how to make one. I've tried different route:
As first thing I've tried creating a file in txt editor with this code:
#!/bin/bash
pip3 install pgzero
echo Installing Pygame Zero
Using later 'chmod 700 Filename' in terminal. It did not worked
I then tried with Apple Scrip, with a code like:
tell application "Terminal"
activate
do script "pip3 install pgzero"
do script "echo Installing Pygame Zero"
end tell
and it kinda worked, but it wasn't an executable
Then I tried with another approach found on google:
echo '#!/bin/bash
pip3 install pgzero
echo Installing PyGame Zero'> ~/Desktop/PygameInstaller.command
chmod 740> ~/Desktop/PygameInstaller.command
and it still didn't worked D:
Can someone land a bit of help? I'm starting feeling lost q,q
Thank you in advance!
In terms of what you want in your shell script, your first attempt is probably close to what you want but the echo should precede the pip3 command. I guess if you change the verb from Installing to Installed, then you could leave it where it is.
$ cat <<EOF > ~/Desktop/PygameInstaller.command
#!/bin/bash
echo Installing Pygame Zero
pip3 install pgzero
EOF
$ chmod 700 ~/Desktop/PygameInstaller.command
The permissions you assign to the script and the script's location depend on who you want to grant execution. If it's only you, then your desktop and 700 should be fine.
Now, if you want to execute the script from a command line like what you would see if you opened an instance of Terminal.app, then you have options.
If you want to fully specify the command, then you would type this (showing prompt which you would not type):
$ ~/Desktop/PygameInstaller.command
If you want to specify only the name of the script, then you would type this after adding ~/Desktop to your PATH:
$ PATH="$HOME/Desktop:$PATH"
$ PygameInstaller.command
If you prefer to type only PygameInstaller, then don't put the code in a file named PygameInstaller.command. Instead, you put the code in a file called simply PygameInstaller.
If you need the script to be executable by everyone, then put it in /usr/local/bin because most people will either have that in their PATH or have no political problem doing so. But you'll have to use the sudo command to elevate your privileges to accomplish that task.
If, however, you want to have that script be treated like any other app that you can launch with a double-click, then you have significantly more work to do.
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.
I'm new to bash and my Mac (about a week) and only 3 months into programming. I've been running into this problem where it ends up being something in my bash profile.
Like changing environment variables in my python so commands like
PATH="/Applications/Postgres.app/Contents/Versions/9.4/bin:$PATH”
export DATABASE_URL=“postgresql://localhost/CHEESE”
export APP_SETTINGS=“config.DevelopmentConfig"
or to get my Postgres in python to work I have to do this
export PATH=/Applications/Postgres.app/Contents/Versions/9.3/bin/:$PATH
recently I just installed virtualenvwrapper and had to do a sudo pip install virtualenvwrapper and running the code in bash would not find it unless I did this
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
So I did some research and I THINK I can permanatly add them to my 'bash profile'. If this is the case I have 2 questions.
Is there a way I can avoid having to manually add the exports in the first place. So I can have the commands working right after installing
How do I add them to my profile. I opened my .bash_profile.swp and it looked intimidating so I didn't touch it because I thought I'd break it. I'm not sure why I had a random pathing for my psycopg2 at the end of the line either( seen in the second link)
http://imgur.com/jedEOn9
http://imgur.com/CYsgVmx
You are correct. Adding these to your .bash_profile will set the environment variables every time you start up your shell. However, as explained here, it is better to put them in your .bashrc and then source that from your .bash_profile. For example,
# put this in your .bashrc
PATH="/Applications/Postgres.app/Contents/Versions/9.4/bin:$PATH"
export DATABASE_URL="postgresql://localhost/CHEESE"
export APP_SETTINGS="config.DevelopmentConfig"
# etc...
# then put this in your .bash_profile
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
This ensures the variables are properly set no matter how you start your shell. The .swp file you are seeing is created by Vim. Just ignore it.
However, there is a better way. The easiest and cleanest way to install software on your computer is with a package manager, which will automatically set the paths for you (among other things). For Mac, I recommend using Homebrew. Once you install it, you can do things like
$ brew install ruby
$ ruby blah blah blah # ruby gets put in the PATH for you!
For python, the standard package manager is pip, which you are already using. However, a word of advice: sudo pip installs packages for the python 2 that comes as part of OS X, which from personal experience I recommend not doing. Instead, install python 2 with Homebrew, and then use the pip (and the python) that comes with that.
I have made a few python scripts, but is there an easier way to run them? I am using cygwin.
python "C:\Users\Desk\Dropbox\scripts\wsort.py" > data11414_unsorted.txt < data11414_sorted.txt
I want something like this (not typing the path name or "python"):
wsort > data11414_unsorted.txt < data11414_sorted.txt
where wsort is a link to my real wsort.py
Add a
Shebang
to the script
#!/bin/python
then invoke like this
wsort.py > data11414_unsorted.txt < data11414_sorted.txt
First, your question has a Windows-style path (backslashes, beginning with C:) rather than a Cygwin path (/cygdrive/c/Users/Desk/Dropbox/scripts/wsort.py). That implies you're not actually using Cygwin, or if you are, you're ignoring a bunch of warnings.
The below assumes you're using Cygwin Bash (which should be what you get if you start Cygwin Terminal from the Start Menu) and Cygwin Python (which you've installed using Cygwin's setup.exe, not a Windows Python installer). If your not, you're making life more difficult for yourself than you need to.
That out the way, there's a bunch of steps you need to take:
First, make the script executable. Use the chmod command for that, from a Cygwin Bash shell:
chmod +x /cygdrive/c/Users/Desk/Dropbox/scripts/wsort.py
Second, tell the system how to execute it. Add the following line to the top of the script:
#!/bin/python
(That's a "shebang". Python sees it as a comment, so doesn't do anything with it, but Cygwin and other Linux-like systems will use that line to see which program to run the script with. In this case, Python.)
Third, make sure your line endings are correct. Cygwin expects Linux line endings and will fail without them. This may not be a problem, but there's no harm in doing this. Run the following command:
dos2unix /cygdrive/c/Users/Desk/Dropbox/scripts/wsort.py
At this point, you'll be able to call the script by specifying the full path to it in Cygwin. You can't yet run it without specifying where the script is explicitly.
The fourth step is making sure the script is "in your path", ie in one of the folders where Cygwin looks for scripts to run. There are lots of ways to do this, but the most sensible is probably to just add your scripts directory to your path. The following command will add your scripts directory to your path whenever you start a new Cygwin session:
echo 'PATH="/cygdrive/c/Users/Desk/Dropbox/scripts:$PATH"' >>~/.bashrc
You will need to restart your Cygwin terminal for that to take effect, however.
At that point, you'll be able to run the script in Cygwin just by typing wsort.py (and thus use it with redirections and so forth as in your question).
Finally, to be able to call it simply as wsort, there's a number of options. The obvious one is just renaming the file. More usefully (and without copying the file or doing anything liable to break with Dropbox syncing things), try creating an alias:
echo 'alias wsort=wsort.py' >>~/.bashrc
Again, you'll need to restart your Cygwin terminal for that to take effect.
Maybe use an alias ?
alias wsort = "Command_Used"