Differences in the ways to running Python scripts - python

I have a very simple Python question, with examples using Django. When running a Python script, do I always have to precede the script filename with the python command?
In the Django tutorial I am following, some commands are as follows:
django-admin.py startproject mysite
However, other are like this:
python manage.py runserver
Why does the top one not need the python command?
Alternatively, if my system knows that all Python scripts are to be executed by my python interpreter, why does the bottom one need the python command at all?

The answer lies in a combination of two things:
The shebang, the first line of a file.
The permissions on the file, namely whether the executable flag is set or not.
Consider the first line of django-manage.py. On my system it is at /usr/local/bin/django-admin.py and the first line is:
#!/usr/bin/python2.7
And the permissions on the file:
-rwxr-xr-x 1 root root 127 Jan 9 13:38 /usr/local/bin/django-admin.py
The shebang tells my OS that I want to execute the file with the interpreter at /usr/bin/python2.7. The x characters in the permissions say that it is an executable file. I don't need to specify python beforehand, because the OS can figure out that stuff automatically from the above pieces of information.
Now for a freshly created manage.py, which I made by running django-admin.py startproject mysite, it looks like this:
#!/usr/bin/env python
And the permissions:
-rw-r--r-- 1 wim wim 249 Feb 17 17:33 manage.py
The shebang indicates to use whatever python interpreter my env is pointing at, so that part is in place already. But the file lacks executable permissions, so just running ./manage.py won't work (yet).
I can make it behave the same as django-manage.py by explicitly setting the executable flag using chmod +x manage.py. After that, you should see the x flags set when you do ls -l in the directory, and you should be able to run the file without specifying python beforehand.
Note: you do still have to use ./manage.py not just manage.py, this discrepancy is because django-admin.py lives in /usr/local/bin/ which is contained in PATH whereas the manage.py file likely doesn't. So we explicitly specify the path at the shell, where . refers to the current directory.

You can make the script executable by using chmod +x script.py, but you need the shebang line, usually #!/usr/bin/python
If you are using a script heavily on a unix-based maching (mac,linux) making an alias can be useful:
alias command="python path/to/script.py"

Related

script.py in path but can't be executed without providing full path

I have a script I have downloaded and installed from GitHub that I am trying to add to my path. Although the script is in the path already somehow I can't run it unless I provide the full path.
echo $PATH
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/Users/me/bin/SCRIPT_FOLDER/
/Library/TeX/texbin
/Users/me/bin/SCRIPT_FOLDER/script.py
Since I am working on Catalina 10.15.7, I saw in other answers that I need to add the script to the .zshrc file, so I did so.
code .zshrc
export PATH=/Users/me/bin/SCRIPT_FOLDER/:$PATH
export PATH=$PATH:/Users/me/bin/SCRIPT_FOLDER/script.py
Despite this the script cannot be run except if I type the entire path
python /Users/me/bin/SCRIPT_FOLDER/script.py --h
What can I try to solve this?
script.py must be executable and the first line must be as shown below.
? echo $PATH
.:./bin:...
? ls
bin
? ls -l bin/script.py
-rwxr-xr-x. 1 x x 40 Mar 9 10:54 bin/script.py
? cat bin/script.py
#!/usr/bin/python
print('Hello world')
? script.py
Hello world
?
If the script is not executable use the chmod command like so:
chmod 755 bin/script.py
Like most command-line programs, Python doesn't consult your PATH for the arguments (e.g., script.py, given the command python script.py). Your PATH only matters when deciding how to resolve the command name (in this case, python). If script.py is in one of your PATH directories (like /Users/me/bin/SCRIPT_FOLDER/), it has the appropriate executable bit set, and it begins with an appropriate shebang line such as #!/usr/bin/env python, then you can run it with the command script.py.

Run Python script using virtualenv

I have a python script named utils (note without any .py extension). Where I have some utility functions. The path is also added in PATH variable.
#!/usr/bin/env python3
import click, sys
#main.command('echo', context_settings=dict(help_option_names=['-h', '--help']))
def echo_test():
click.echo("Hello World")
sys.exit(0)
It works fine. Now I can run from anywhere utils echo.
I am trying to make the script to use virtualenv instead of the global python. I have tried
#!/path/to/venv/bin python3
import click, sys
Then it throws me error permission denied
Permissions for utils file are -rwxr-xr-x
Any idea how could I use venv with script.
If your code is pasted correctly, your problem is that you are trying to execute a directory with your she-bang, not Python, because you have a space rather than a slash as a separator:
#!/path/to/venv/bin python3
rather than:
#!/path/to/venv/bin/python3
EDIT: By the way, is there a reason you want to change the code and not just activate the virtual environment, like it's supposed to be used?
If you want to do it, you can just:
$ source path/to/venv/bin/activate<.optional_extension>
You need the optional extension if you use a shell other than Bash (probably other Bourne-like shells too).
Try changing the file permissions via this command:
chmod 755
chmod -R 755 on the /usr/lib/python/site-packages/virtualenv
or even
chmod +x
Suggest you read the man page for chmod by using this command
man chmod
if you are not sure.

Execute a python script as a command

I'm writing a python script which will be placed in a location. I want to execute it just like a command. for ex.
$ find_branch test
where find_branch is a script placed in anywhere in the system.
I would like to know how to achieve this. I can run it on the place where the script is present by chmod u+x on the script and removing the .py from the script
sudo nano /usr/bin/testpyscript
Then inside the script:
#!/usr/bin/python
print("I'm a python script")
Give it x permission:
sudo chmod +x /usr/bin/testpyscript
Now you can use it as a regular command:
bash-4.2$ testpyscript
I'm a python script
It doesn't have to be exactly at /usr/bin, any location that is inside your $PATH will do. Let's say you want it to be located at some folder inside your home directory, you could do something like this:
pwd
/home/brunorb
mkdir somedir
sudo mv /usr/bin/testpyscript somedir/
export PATH=$PATH:/home/brunorb/somedir/
testpyscript # from any folder in the system
I'm a python script
Make sure python has been added to your path and #!/usr/bin/python is located at the top of your script.
Note You could just try adding your script to your /usr/local/bin/ directory and give it the proper permissions.
sudo cp <your script> /usr/local/bin/
You have a number of options on how to achieve this.
Add the location where you put the script to your PATH environment variable, for example in your ~/.bashrc script:
export PATH="${PATH}:/folder/where/you/put/the/script"
Install the script to a location that is already on your path. It does not have to be a system folder like /usr/bin. Many default Bash setups will include ~/bin in your PATH.
Give the full path to your script on the command line:
/folder/where/you/put/the/script/find_branch test
Run the script through Python. This is very similar to option #2:
python /folder/where/you/put/the/script/find_branch test
Create an alias for the script in your environment. In bash you would do something like the following in your ~/.bashrc:
alias find_branch='/folder/where/you/put/the/script/find_branch'
OR
alias find_branch='python /folder/where/you/put/the/script/find_branch'
For options #1, #2, #3 and #5a to work properly, you should have a shebang with the version of python as the first line of the script. Any of the following will do, depending on how you have/want your environment set up:
#!/usr/bin/python
#!/usr/bin/python2
#!/usr/bin/python3
#!/usr/bin/env python
#!/usr/bin/env python2
#!/usr/bin/env python3
Finally, you do not have to remove the .py extension from the script if you do not want to. Many bash scripts have a .sh extension, for example, which does not prevent them from running as-is. You just have to include the extension in the name of the script when you run it.

Turn an application or script into a shell command

When I want to run my python applications from commandline (under ubuntu) I have to be in the directory where is the source code app.py and run the application with command
python app.py
How can I make it (how is it conventionally done) to run the application from arbitrary directory with the command: app ? Similarly as you type ls, mkdir and other commands?
thank you
Add a shebang line at the beginning of your file:
#!/usr/bin/env python
Make your file executable by calling
chmod +x app.py
in the shell.
Move it to some location included in the PATH environment variable and rename it to app. Alternatively, add the path of the directory containing app to the PATH environment variable by adding the line
export PATH=$PATH:/path/to/app
to your .bash_profile.
Add the directory that the script is in to your path, make it executable, and add a proper shebang line.
In your .bashrc:
PATH=$PATH:/dir/to/the/script
Executable:
chmod +x myscript.py
At the top of the script, add the shebang line:
#!/usr/bin/env python
Then, from anywhere, you can just do:
myscript.py
(Note that you don't need a .py suffix, it could be called anything, e.g. app if you have a proper shebang line).
Add a shebang: as the top line of the file: #!/usr/bin/python or #!/usr/bin/python3 (you can use the python -B to prevent generation of .pyc files, which is why I don't use /usr/bin/env)
Make it executable: You will need to do chmod +x app.py
(optional) Add directory to path, so can call it anywhere: Add a directory with your executable to your $PATH environment variable. How you do so depends on your shell, but is either export PATH=$PATH:/home/you/some/path/to/myscripts (e.g. Linux distros which use bash) or setenv PATH $PATH:/home/you/some/path/to/myscripts (e.g. tcsh like in Mac OS X). You will want to put this, for example, in your .bashrc or whatever startup script you have, or else you will have to repeat this step every time you log in.
app.py will need to be in the myscripts (or whatever you name it) folder. You don't even need to call it app.py, but you can just rename it app.
If you wish to skip step #3, you can still do ./app to run it if you are in the same directory.
Probably you want to symlink to your file location instead of adding another location to the path
chmod +x app.py
ln ~app.py /opt/local/bin/app
...assuming that /opt/local/bin is already in your path,.
Also, do not forget to add the shebang line to the first line of your script:
#!/usr/bin/env python
A solution some what different from the ones mentioned here: Use an alias.
alias app='python /path/to/app.py'
Add the above line to your ~/.bashrc or ~/.bash_login file (or preferably to ~/.bash_aliases if you are on Ubuntu). Then you can simply use your script as a command line tool with app.
No need to add a shebang (thereby modifying your existing Python script), no need to make the script executable and no need to change your PATH.
I'm pretty sure you have to make the script executable via chmod +x and put it in the PATH variable of your system.

Altering my python path: helloworld.py returns command not found—

Massive apologies for this embarrassing question—
I'm using my MacBook Pro, running snow leopard, and using Python 2.7.1. Trying to run my first script and all the first pages of all my tutorials are laughing at me:
Let me preface with:
$ whereis python
/usr/bin/python
$ which python
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
(Is this my issue?)
I wrote helloworld.py to /users/charles in vim:
$ vim helloworld.py
#!/usr/bin/python
# Hello World Python Program
print "Hello World!";
When trying to run it from terminal:
$ helloworld.py
-bash: helloworld.py: command not found
When trying to run it from python:
$ python
>>> helloworld.py
Traceback (most recent call last):
File :<stdin>", line 1, in <module>
NameError: name 'helloworld' is not defined
From Dive Into Python (not sure if this is pertinent):
$ python
>>> import sys,os
>>> print 'sys.argv[0] =',sys.argv[0]
sys.argv[0]=
>>> pathname=os.path.dirname(sys.argv[0])
>>> print 'path=',pathname
path=
>>> print 'full path=',os.path.abspath(pathname)
full path= /Users/charles
I'm befuddled! Do I need to alter one of my paths so it finds my script?
I'm absolutely new to programming, I actually just found out that terminal was something you could use.
Thanks!
Let's start with the first error you received. Understanding error messages is important.
-bash: helloworld.py: command not found
This indicates that helloworld.py is not a command that can be executed. To run the file, you then have two options:
Run it using the python interpreter. python helloworld.py
Make the file executable and then run it directly. ./helloworld.py
To make files executable in a *nix environment, you have to change their mode to allow execution. In order to do this, you use the chmod command (man chmod for more info).
chmod +x helloworld.py
This assumes that you are in the directory containing the helloworld.py file. If not, cd there first or use the full path.
The ./ is necessary because it tells the shell to run the file located here, not by looking in $PATH. $PATH is a list of possible executable locations. When you try to run helloworld.py directly, the shell tries to look for it in $PATH. You want to run the local file, so you have to prefix it with ./, which means "from here".
As an aside, note the first line of your python script:
#!/usr/bin/python
This is called a shebang line and tells system to use the /usr/bin/python executable to load the file. Internally, that means that the program loader will be doing /user/bin/python helloworld.py.
Finally, when you called python with no arguments, you were dropped into an interactive Python interpreter session. >>> helloworld.py in this environment is not referencing the file of that name, it's just interpreted as python code. Invalid python code. This is why you get your second error, NameError: name 'helloworld' is not defined.
To turn a Python module or script into a standalone program on a UNIX system you have to do two things:
1.) Make sure you have the "shebang" in the top of your script:
#!/usr/bin/python
2.) Make sure the script file is executable. This is done using the chmod command:
chmod +x /path/to/helloworld.py
/path/to/ being the fully qualified file path to your script. If it's in the current directory, then you can omit the path.
% ls -l
total 0
drwxr-xr-x 2 jathan jathan 60 2011-04-13 15:28 ./
drwxrwxrwt 12 root root 6.5K 2011-04-13 15:28 ../
-rw-r--r-- 1 jathan jathan 0 2011-04-13 15:28 helloworld.py
It's in my current directory, so let's make it executable!
% chmod +x helloworld.py
% ls -l
drwxr-xr-x 2 jathan jathan 60 2011-04-13 15:28 ./
drwxrwxrwt 12 root root 6.5K 2011-04-13 15:28 ../
-rwxr-xr-x 1 jathan jathan 0 2011-04-13 15:28 helloworld.py*
See the "x"s in the permission bits on the left? You've done it! Now we can run it:
% ./helloworld.py
Hello World!
Lastly, never use semicolons as line-endings in Python. It's not required and it's ugly!
Wanted to add my 2 cents: Apart from permissions and path answers above, there is one more situation where you may still face the same error.
In-spite of correct permissions and the shebang header, you may still get the same "Command not found" error if you've originally written the file in Windows and copied it over to Linux. Due to differing line-ending characters, there will be extra '\r' characters on the lines.
This happens because there are non-printable characters in the file. Examing it by doing:
cat -v <filename>:
#!/usr/intel/bin/python^M
The extra "^M" is the problem. Use 'dos2unix' to convert the file and then it'll run fine.
as others said you should chmod +x your file to make it executable and if you don't want to put "./" in your coomand line you should add your current place as system path:
export PATH=$PATH:.
If you're already within python, the syntax to load your script is not helloworld.py :
import helloworld
or
from helloworld import *
you only use the extension .py when you're running python with a script as a command line argument.
No need to apologize, have to start somewhere, and the error messages can be cryptic when you're having basic syntax problems.
Make sure your terminal's current working directory is where your .py file is.
EDITED:
try doing /usr/bin/python helloworld.py on commmand line

Categories

Resources