How do I install a script to run anywhere from the command line?
Solution 1
The best place to put things like this is /usr/local/bin
.
This is the normal place to put custom installed binaries, and should be early in your PATH
.
Simply copy the script there (probably using sudo
), and it should work for any user.
Solution 2
Walkthrough of making a python script available anywhere:
Make a python script:
cd /home/el/bin
touch stuff.py
chmod +x stuff.py
Find out where your python is:
which python
/usr/bin/python
Put this code in there:
#!/usr/bin/python
print "hi"
Run in it the same directory:
python stuff.py
Go up a directory and it's not available:
cd ..
stuff.py
-bash: stuff.py: command not found
Not found! It's as we expect, add the file path of the python file to the $PATH
vi ~/.bashrc
Add the file:
export PATH=$PATH:/home/el/bin
Save it out, re apply the .bashrc, and retry
source ~/.bashrc
Try again:
cd /home/el
stuff.py
Prints:
hi
The trick is that the bash shell knows the language of the file via the shebang.
Solution 3
Just create ~/bin
and put export PATH=$PATH:$HOME/bin
in your bashrc/profile. Don't mess with the system, it will bite you back, trust me.
Few more things (relevant to the question but not part of the answer):
- The other way
export PATH=$HOME/bin:$PATH
is NOT safe, for bash will will look into your~/bin
folder for executables, and if their name matches with other executables in your original$PATH
you will be surprised by unexpected/non working command execution. - Don't forget to
chmod+x
when you save your script in~/bin
. - Be aware of what you are putting in your
~/bin
folder, if you are just testing something or working on unfinished script, its always better to use ./$SCRIPT_NAME from yourCWD
to execute the script than putting it under~/bin
.
Solution 4
The quick answer is to symlink
your script to any directory included in your system $PATH
.
The long answer is described below with a walk through example, (this is what I normally do):
a) Create the script e.g. $HOME/Desktop/myscript.py
:
#!/usr/bin/python
print("Hello Pythonista!")
b) Change the permission of the script file to make it executable:
$ chmod +x myscript.py
c) Add a customized directory to the $PATH
(see why in the notes below) to use it for the user's scripts:
$ export PATH="$PATH:$HOME/bin"
d) Create a symbolic link to the script as follows:
$ ln -s $HOME/Desktop/myscript.py $HOME/bin/hello
Notice that hello
(can be anything) is the name of the command that you will use to invoke your script.
Note:
i) The reason to use $HOME/bin
instead of the /usr/local/bin
is to separate the local scripts from those of other users (if you wish to) and other installed stuff.
ii) To create a symlink you should use the complete correct path, i.e.
$HOME/bin
GOOD ~/bin
NO GOOD!
Here is a complete example:
$ pwd
~/Desktop
$ cat > myscript.py << EOF
> #!/usr/bin/python
> print("Hello Pythonista!")
> EOF
$ export PATH="$PATH:$HOME/bin"
$ ln -s $HOME/Desktop/myscript.py $HOME/bin/hello
$ chmod +x myscript.py
$ hello
Hello Pythonista!
Solution 5
you can also use setuptools
(https://pypi.org/project/setuptools/)
- your script will be:
def hi():
print("hi")
(suppose the file name is hello.py
)
-
also add
__init__.py
file next to your script (with nothing in it). -
add
setup.py
script, with the content:
#!/usr/bin/env python3
import setuptools
install_requires = [
'WHATEVER PACKAGES YOU NEED GOES HERE'
]
setuptools.setup(
name="some_utils",
version="1.1",
packages=setuptools.find_packages(),
install_requires=install_requires,
entry_points={
'console_scripts': [
'cool_script = hello:hi',
],
},
include_package_data=True,
)
- you can now run
python setup.py develop
in this folder - then from anywhere, run
cool_script
and your script will run.
jeffbr13
Updated on September 22, 2020Comments
-
jeffbr13 over 3 years
If I have a basic Python script, with it's hashbang and what-not in place, so that from the terminal on Linux I can run
/path/to/file/MyScript [args]
without executing through the interpreter or any file extensions, and it will execute the program.
So would I install this script so that I can type simply
MyScript [args]
anywhere in the system and it will run? Can this be implemented for all users on the system, or must it be redone for each one? Do I simply place the script in a specific directory, or are other things necessary?
-
plaes almost 13 yearsNo, please do not use /usr/bin! Use /usr/local/bin for these purposes.
-
themaestro almost 13 yearsAgreed, this is quite unadvisable. Go with /usr/local/bin instead
-
Evpok almost 13 yearsOr, uglier but sometimes useful, add an arbitrary directory to $PATH.
-
agf almost 13 yearsYou'd either have to mess with an important global setting that you really don't want to mess up or add to user's settings individually.
-
Dana the Sane almost 13 yearsTrue, but this is the standard. If this is an important distinction, it's up to the system administrator to put policy in place to show/hide executable directories (like with
sbin
). -
Keith Thompson almost 13 yearsUse
$HOME
, not/home/$USER
. And personally, I put$HOME/bin
at the front of my$PATH
precisely so I can override other commands. -
Sudhi almost 13 yearsthanks for pointing out
$HOME
. But kindly allow me to disagree with your second point. You know what you are doing when you put ~/bin before $PATH, many (if not most) people don't know about the implications of these mechanism. -
Keith Thompson almost 13 yearsI see your point. On the other hand, putting something in $Home/bin and having it quietly not work could be even more confusing. Perhaps one could have one directory at the front of $PATH for deliberate overrides, and another at the end for other personal commands (with names carefully chosen to avoid collisions). I just now thought of that, and I'm not sure how good an idea it is. Bottom line: $PATH management is non-trivial.
-
Keith Thompson almost 13 yearsAnother thought: sometimes the answer to "people don't know about the implications" is to teach them.
-
Sudhi almost 13 years@Keith : agreed, $PATH management is non-trivial and must be exercised with caution. As for teaching people the implications of such non-triviality, I believe the 1st point of my answer and our comments will lead anyone with sufficient curiosity into more detailed and authoritative sources of Bash architecture. So I guess we are teaching them, indirectly.
-
Louis Thibault over 11 yearsIs there a way to do this automatically with setuptools?
-
Matt Fletcher about 11 years+1 for recommending
/usr/local/bin
. Make sure to make the scripts executable too!sudo chmod 744 /usr/local/bin/yourscript
should do it. -
user2233949 about 7 yearsThis should be the answer in my opinion. /usr is for stuff like this, there's no messing with PATH, and the actual script can live anywhere you want. Nice and simple, yet effective.
-
Destaq almost 4 yearsThis does not work, it shows a command not found error.
-
Alon Gouldman almost 4 years@Destaq you should have your venv active when running the command
-
Jimmy2027 over 3 yearsbest answer here, cf python-packaging.readthedocs.io/en/latest/…
-
Charlie Parker about 3 yearshow is this different from using the
-m
flag in python? The description of such as a flag says thats the python way to do it?Searches sys.path for the named module and runs the corresponding .py file as a script.
-
Charlie Parker about 3 yearshow is this different from using the
-m
flag in python? The description of such as a flag says thats the python way to do it?Searches sys.path for the named module and runs the corresponding .py file as a script.
-
Charlie Parker about 3 yearshow is this different from using the
-m
flag in python? The description of such as a flag says thats the python way to do it?Searches sys.path for the named module and runs the corresponding .py file as a script.
-
Charlie Parker about 3 yearshow is this different from using the
-m
flag in python? The description of such as a flag says thats the python way to do it?Searches sys.path for the named module and runs the corresponding .py file as a script.
-
agf about 3 years@CharlieParker Basically, they're the same except for what you have to type to run them. It's just about what you want / need the user experience to be.