I have a python project with multiple files and a cmd.py which uses argparse to parse the arguments, in the other files there are critical functions. What I want to do is: I want to make it so that if in the command line I were to put cmd -p hello.txt it runs that python file.
I was thinking that I could just simply move the cmd.py file to somewhere like /usr/bin/ or some other directory included in the $PATH, however since I have other files which work with my cmd.py, there will be multiple files in my /usr/bin.
Another thing that I could do is to make a symbolic link between the cmd.py and /usr/bin/cmd like this: ln -s /path/to/cmd.py /usr/bin/cmd, but then where do i put the cmd.py? and is this best practice?
Note: I intend for this to work on Linux and MacOS X, not windows
The usual way to do this is to define a set of entry points in setup.py and let the packaging infrastructure do the heavy lifting for you.
setup(
# ...
entry_points = {
'console_scripts': ['cmd = cmd:main'],
}
)
This requires setuptools.
Here is some documentation for this facility: https://python-packaging.readthedocs.io/en/latest/command-line-scripts.html
For one thing I don't recommend installation in /usr/bin as that's where system programs go. /usr/local/bin or another custom directory added to $PATH could be appropriate.
As for getting it to run like a typical program, name it cmd, wherever you put it, as the extension is not necessary, and add this line to the top of the program:
#!/usr/bin/env python
(You may want to specify python3 instead of just python if you want to ensure Python 3.x is used.)
Then it can be made executable with chmod +x <path to your program>. Ensure that you have the necessary privileges to do this (i.e. sudo may be necessary).
You can add a folder to your path.
in .bashrc add following
export PATH=[New_Folder_Path]:$PATH
put the python program in your path_folder created at step 1.
make it executable : chmod u+x [filename]
open a new terminal, and you should be able to call the python program
NOTE: make sure to put the shebang in your python-file : #!/usr/bin/env python3
Related
Problem to solve
I have a python script called myscript.py in a directory.
To run myscript.py, I have to open terminal in the same directory and do python myscript.py or python path_to_the_py_file
What I want to achieve
I can open a instance of terminal anywhere, anytime and do myscript or myscript arguments -options. By doing this, I should be able to run the script.
I want to implement something like pip command or the howdoi package.
When I enter myscript in terminal I should not get:
myscript: The term 'myscript' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
If you have any confusion please ask in comments. if the title needs improvement, feel free to edit the question.
There seems to be quite a few things in this question.
First, you want to make you file executable.
chmod +x /path/to/your/script.py
Then, since this is an interpreted language, you’ll have to specify the interpreter in a shebang at the top of the file.
#!/usr/bin/env python
OR
#!/usr/bin/env python3
Finally, you’ll have to put it in your PATH environment variable, which can be done in a variety of ways, simplest might be symlink in ~/bin or ~/.local/bin, depending on what you have.
Also, this will make script.py available as an executable, you can rename it or rename its symlink to just script if you don’t want .py.
I have a script/app/program written in python 3. I uploaded it to my Ubuntu box and changed the permission to allow execution by all. I am able to run python myapp.py with no problem but I cannot run myapp.py. I get an error that it is not a recognized command. I have at the top
#!/usr/bin/env python3
That should be right from all that I've read so far. I even tried
#!/usr/bin/python3
in the program referred to as myapp.py
Neither of them work.
I was following an online course and all was going well until we got to that point of running python scripts like regular programs by setting the execute setting.
If you are talking about, executing it from any directory, you need to do two things.
Setting the path variable. Lets say I need to execute Test.py, which is in Desktop, from any directory
export PATH=$PATH:/home/thefourtheye/Desktop/
Giving execute permission to the file
chmod 755 /home/thefourtheye/Desktop/Test.py
Then I can execute it by simply typing Test.py.
You cannot execute file in unix by name without directory name due to some security considerations, so you have to add . as directory (it will look like ./myapp.py)
. isn't on your path (and it probably shouldn't be for security reasons), so Ubuntu won't look in the current directory for a myapp.py program to run. You need to explicitly specify ./myapp.py to indicate that you want to run the myapp.py file in the current directory.
You should either call it as
./myapp.py
or the current directory should be in the PATH environment variable (either as full directory path name or as '.' which indicates the dynamic current path), check with
echo $PATH
to add it you can run
export PATH=$PATH:.
If you want to run it like:
user#machine:~$ myapp.py
You must put the script in the /usr/bin/ or /bin/ or something similar. In other case you must run like:
user#machine:~/appFolder/$ ./myapp.py
did you try:
$ sudo chmod a+x myapp.py
then run the python code using:
$ ./myapp.py
For linux users, may be text format dos/unix problem!
try,
sudo dos2unix name_of_your_script
then shebangs will probably get to work properly! That was what happened to me.
PS:
Ofcourse, also your script has to be executable
(sudo chmod +x name_of_your_script )
Is there a portable way to run a python script from a shell without writing its full path?
For example in Linux, I would like while in my home directory
cd ~
to be able to run a python script called run.py that is in say, ~/long/path/to/run.py, but I want to run it by simply typing
python run.py
instead of
python ~/long/path/to/run.py
I would hope for some kind of search path list that contains several directories just like the PATH variable, so that python run.py runs the first run.py it encounters in one of the directories.
I have considered turning run.py into an executable and adding its directory the system PATH variable, but could not find a portable way of making a python script executable.
EDIT
One year later after asking it, I am a bit less noob, and I see that my question was not very clear and did not make much sense, so after a question upvote I'll clarify some things.
1) Portable.
When I asked this I said portable. However what portable means is not clear in this case, and I did not give much emphasis to it.
the platforms: should work on POSIX (Linux, MacOS, etc.) and Windows
this still does not make much sense since windows uses cmd.exe, and POSIX uses sh, so each one could run the commands with a different syntax. So let's say that the most portable thing possible would be to feed the same input to both sh and cmd.exe, running the python script in both cases. In this case, you could run the same command from an ANSI C system function, which uses sh on POSIX and cmd on Windows. ANSI C being one of the few things that is common to Windows and POSIX, the question makes some sense in that case.
2) Executable
Next, the phrase turning run.py into an executable, is not very clear. By that I was talking about the Linux strategy of chmod +x run.py, add a shebang #!/usr/bin/env python, and adding its directory the system add ~/long/path/to/ the PATH enviroment variable. But then this won't work for windows because windows does not support an executable file metadata property like Linux and because /usr/bin/env does not necessarily exist in Windows.
3) Extension
Finally, in my head I was hoping for a solution that does not specify what kind of file run is, so that if someday we decide to make it, say, a perl file, no interfaces would change.
Therefore, writing run.py would be bad because it would specify the filetype; it would be better to be able to write just run
If the directory containing run.py is on the module search path (for example, PYTHONPATH environment variable), you should be able to run it like this:
python -m run
Here is the documentation on the -m command line option:
-m module-name
Searches sys.path for the named module and runs the corresponding .py file as a script.
You can make a python script executable by adding
#!/usr/bin/env python
to the beginning of the file, and making it executable with chmod +x.
Answer after the clarification edit
I prefer the following approach to the one suggested by #F.J. because it does not require users to specify the file type. Please note that this was not specified in the original question, so his answer to the original question was correct.
Lets call the file pytest.py to avoid conflicts with a possible existing run program.
On POSIX (MacOs, linux) do what #Petr said, which is based on what #alberge said:
chmod +x
add shebang #!/usr/bin/env python
create a directory and add it to path. Usual locations on Linux are: ~/bin/ for a single user, /usr/local/bin/ for all users
symlink (cp -s) the file under your PATH with basename pytest instead of pytest.py
On windows:
create a dir and add it to PATH. AFAIK, there is no conventional place for that, so why not C:\bin\ and ~\bin\?
add .PY to the PATHEXT environment variable so that Windows will recognize files with python extension as runnable files without requiring you to type the extension
associate python files with the python.exe interpreter (Windows Explorer > right click > check "Always use the selected program"). There is an option on the python installer that does this for you.
symlink pytest with extension into the dir under PATH (using Link Shell Extension from Windows Explorer or mklink name dest from cmd )
Now system( "pytest" ); should work in both systems ( sh under Linux, cmd under Windows )
Make python file executable (as "alberge" stated above)
Create some directory and put this directory into your PATH variable
In this directory, create links to your python scripts
I have a small program in python that consists in one .py file plus a directory of data files used by the program.
I would like to know the proper way to create an installation procedure for a user with admin rights on Linux so that he can install the program on his system and use it from the command line, with options and parameters. EDIT: The part I am having trouble with is to have the program, once installed, retrieve the data files, contained in a 'data' sub-folder.
Would a setup script that installs the executable program file in /usr/local/bin and the data folder in /usr/share/my_program/data be an acceptable solution? Something like:
#!/bin/bash
# Launch with sudo
chmod +x program.py
cp program.py /usr/local/bin
cp -r data /usr/share/my_program
echo Installation complete
Now, in order to do that, I have to assume, in the program, that the data files are going to be in /usr/share/my_program/data. But I would also leave the user the choice of using the program without installing it. Then I would have to assume that the data are in './data', relative to the executable program file. How should I solve this problem? I can think of a few ways, but my feeling is that I am creating a mess where there should be a clear and correct answer.
Currently, I am considering using a try except clause:
try:
find data from /usr/share/my_program && set path accordingly
except:
set path to the data as './data'
Again, I feel it is a bit convoluted. How would you proceed for the installation?
Am I wrong that the setup.py method (ie: python setup.py install), is only for installing modules, later to be used from within the interpreter or other scripts?
Yes. You're wrong.
You can install into Python's scripts directory. Keep reading up on all the things setup.py can do. http://docs.python.org/distutils/setupscript.html#installing-scripts
This is actually very, very simple. And it has nothing to do with Python.
A Python script can be run from anywhere. Linux gives you a wide, wide variety of ways to make an executable file (/path/to/my_program.py) runnable.
All of those wide, wide variety of ways have three things in common. Three thing that are central to Linux and has nothing to do with Python at all.
The file must be on the user's PATH.
The file must have "execute" privilege (chmod +x ...).
The file must begin with #!/usr/bin/env python.
How do make this happen?
For #1.
You can check the PATH and put the file in any of the directories on the PATH. There are lots of standard choices for this. /usr/local/bin, for example.
You can modify the user's PATH to include some new directory. /path/to, for example, so that /path/to/my_program.py can be found.
For #2. You execute the appropriate chmod +x.
For #3. You write the appropriate line of code.
For more information read up on "Linux Shell". All "shell" programs have the same three features. bash. csh, python, perl, etc., etc., etc.
retrieve the data files, contained in a 'data' sub-folder, while refering to them as ./data/this_file.dat, for example.
That would be a poor design.
Linux (outside Python) provides a lot of ways to find useful data files.
Install them in a known location with a known path. /usr/local/share comes to mind. This may not be the best location, but it's reasonably popular.
Use environment variables. MYAPP_HOME, for example, can be set to the location of the file. The you can use os.path.join( os.environ['MYAPP_HOME'], 'data', 'this_file.dat' ) Very popular.
Use the __file__ variable to find out where your script is located. Then use os.path to locate the directory and assemble the data path with os.path.join( this_directory, 'data', 'this_file.dat' )
If you have no external dependencies, such as databases or settings that need to be configured, a simple setup.sh script should do.
DIR=`pwd`
NAME=my_app.py
echo "#!/usr/bin/env sh
python $DIR/my_app.py" > /usr/sbin/$NAME
chmod a+x /usr/sbin/$NAME
It can get more complicated depending on your needs.
You could create an executable zip file that contains your script and data files that it uses. An installation just need to put this file somewhere in $PATH and make it executable: chmod +x my-program.
python: can executable zip files include data files?
If you create an appropriate setup.py that specifies how to install your data files and the script then there are many more options to install the program e.g.,
$ pip install --user http://example.com/your-program.tar.gz
where pip can be installed via a system packager, your-program.tar.gz you could create using python setup.py sdist.
Based on the answers of this question, and to those in the question suggested by FakeRainBrigand (How can I know the path of the running script in Python?), I created an install script that goes like this:
#!/bin/bash
mkdir /usr/share/my_program
chmod +x my_program.py
cp my_program.py /usr/local/bin
cp -r data /usr/share/my_program
echo Installation completed
And added the following code in my program:
if os.path.dirname(__file__) == "/usr/local/bin":
DATA_PATH = "/usr/share/my_program/data"
elif os.path.dirname(__file__) == ".":
DATA_PATH = "./data"
else:
print "You do not have a working installation of my_program"
print "See the installation procedure in the README file"
sys.exit(1)
I then use os.path.join(DATA_PATH, "file-to-reach.txt") so that the program can reach it's data, found under /usr/share/my_program.
I would be glad to have comments if a more accepted method is available.
This answer was posted as an edit to the question Proper installation script for a small Python program (Not module) under Linux by the OP Morlock under CC BY-SA 3.0.
I'm writing a pretty basic application in python (it's only one file at the moment). My question is how do I get it so the python script is able to be run in /usr/bin without the .py extension?
For example, instead of running
python htswap.py args
from the directory where it currently is, I want to be able to cd to any directory and do
htswap args
Thanks in advance!
Simply strip off the .py extension by renaming the file. Then, you have to put the following line at the top of your file:
#!/usr/bin/env python
env is a little program that sets up the environment so that the right python interpreter is executed.
You also have to make your file executable, with the command
chmod a+x htswap
And dump it into /usr/local/bin. This is cleaner than /usr/bin, because the contents of that directory are usually managed by the operating system.
The first line of the file should be
#!/usr/bin/env python
You should remove the .py extension, and make the file executable, using
chmod ugo+x htswap
EDIT: Thomas points out correctly that such scripts should be placed in /usr/local/bin rather than in /usr/bin. Please upvote his answer (at the expense of mine, perhaps. Seven upvotes (as we speak) for this kind of stuff is ridiculous)
Shebang?
#!/usr/bin/env python
Put that at the beginning of your file and you're set
add #!/usr/bin/env python to the very top of htswap.py and rename htswap.py to htswap then do a command: chmod +x htswap to make htswap executable.
I see in the official Python tutorials, http://docs.python.org/tutorial/index.html, that
#! /usr/bin/env python
is used just as the answers above suggest. Note that you can also use the following
#!/usr/bin/python
This is the style you'll see for in shell scripts, like bash scripts. For example
#!/bin/bash
Seeing that the official tuts go with the first option that is probably your best bet. Consistency in code is something to strive for!