How do I install a script to run anywhere from the command line?

58,312

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):

  1. 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.
  2. Don't forget to chmod+x when you save your script in ~/bin.
  3. 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 your CWD 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/)

  1. your script will be:
def hi():
    print("hi")

(suppose the file name is hello.py)

  1. also add __init__.py file next to your script (with nothing in it).

  2. 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,
    )

  1. you can now run python setup.py develop in this folder
  2. then from anywhere, run cool_script and your script will run.
Share:
58,312
jeffbr13
Author by

jeffbr13

Updated on September 22, 2020

Comments

  • jeffbr13
    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
    plaes almost 13 years
    No, please do not use /usr/bin! Use /usr/local/bin for these purposes.
  • themaestro
    themaestro almost 13 years
    Agreed, this is quite unadvisable. Go with /usr/local/bin instead
  • Evpok
    Evpok almost 13 years
    Or, uglier but sometimes useful, add an arbitrary directory to $PATH.
  • agf
    agf almost 13 years
    You'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
    Dana the Sane almost 13 years
    True, 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
    Keith Thompson almost 13 years
    Use $HOME, not /home/$USER. And personally, I put $HOME/bin at the front of my $PATH precisely so I can override other commands.
  • Sudhi
    Sudhi almost 13 years
    thanks 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
    Keith Thompson almost 13 years
    I 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
    Keith Thompson almost 13 years
    Another thought: sometimes the answer to "people don't know about the implications" is to teach them.
  • Sudhi
    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
    Louis Thibault over 11 years
    Is there a way to do this automatically with setuptools?
  • Matt Fletcher
    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
    user2233949 about 7 years
    This 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
    Destaq almost 4 years
    This does not work, it shows a command not found error.
  • Alon Gouldman
    Alon Gouldman almost 4 years
    @Destaq you should have your venv active when running the command
  • Jimmy2027
    Jimmy2027 over 3 years
  • Charlie Parker
    Charlie Parker about 3 years
    how 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
    Charlie Parker about 3 years
    how 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
    Charlie Parker about 3 years
    how 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
    Charlie Parker about 3 years
    how 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
    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.