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?
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.
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.
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.
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 your CWD to execute the script than putting it under ~/bin.
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!
Just create symbolic link to your script in /usr/local/bin/:
sudo ln -s /path/to/your/script.py /usr/local/bin/script
Putting the script somewhere in the PATH (like /usr/local/bin) is a good solution, but this forces all the users of your system to use/see your script.
Adding an alias in /etc/profile could be a way to do what you want allowing the users of your system to undo this using the unalias command. The line to be added would be:
alias MyScript=/path/to/file/MyScript
i find a simple alias in my ~/.bash_profile or ~/.zshrc is the easiest:
alias myscript="python path/to/my/script.py"
Type echo $PATH in a shell. Those are the directories searched when you type command, so put it in one of those.
Edit: Apparently don't use /usr/bin, use /usr/local/bin
Acording to FHS, the /usr/local/bin/ is the good place for custom scripts.
I prefer to make them 755 root:root, after copying them there.
I have created a function configure_propeties() in configure.py that I'm trying to call in a bash script using the following command:
python3.6 -c "import configure; print configure.configure_properties()"
After executing the the bash script I get the following warning:
warning
Both the script and configure.py are in the same directory. Not sure what's happening it doesn't seem to fail on the import. Has anyone seen this issue before?
print "blabla" its only available in python 2, with python 3 you have to use parentheses print("blabla"), it would be better to set your python script inside .py file, just make sure the python executable is in your PATH environment variable then add in your script
python3 path/to/the/python_script.py
In the bash script file bashFile.sh, put this :
#!/bin/bash
python3 path/to/the/python_script.py
then you can execute your bash file bashFile.sh :
bash path/to/bashFile.sh
Use parentheses for print, as is necessary for Python 3
I have a problem: How can I run on terminal a script of python without using python3 before the name of script?
For example:
For run my script I should write on terminal this:
$ python3 nameofthescript.py args
But I want that you to write this:
$ nameofthescript args
How can I do?
First, obviously rename the file
mv nameofthescript.py nameofthescript
Next, add this to the beginning of your file:
#!/usr/bin/env python3
Then make the file executable:
chmod +x nameofthescript
Now you should be able to run the file as:
./nameofthescript
If you want it to run from any directory, you have to move it to a directory inside your $PATH (usually /usr/local/bin):
mv nameofthescript /usr/local/bin
Hi there I have a shell command that I need to put into crontab to run periodically.
I have test my script in the working directory, say my home directory, and it works fine. Something similar like:
python myscript.py <input >/tmp/output
As you can see the myscript.py and input file are located in my home directory and the output should go into the tmp folder.
I know I could use 'which' command to get the path of python and 'pwd' command to get the working directory while I am done with my test. However, I am wondering is there a tool or command to translate that into the complete version easily.
How could I easily replace every thing with the full path so I could put that 'full path version' into crontab and it could be recognized globally.
python myscript.py <input >/tmp/output
... magic ...
/usr/bin/python /home/myAccount/myscript.py </home/myAccount/input >/tmp/output
For bash you could do that easily with one command:
echo "$(type -P python) $HOME/myscript.py <$HOME/input >/tmp/output"
And that doesn't rely on external command like which or pwd. You can also place that on a script. Just add #!/bin/bash on the header.
Here is my compile.sh:
#!/bin/bash
coffee -o public/app/ -cwb public/src/
When i open script by double click:
File not found: public/src/.coffee
It is work only from terminal: ./compile.sh
May be there is best way to compile CoffeScript on Mac OS X?
If you are trying to get a coffeescript "script" to execute by "running it", similar to other scripts in a unix environment, you could try something like the following in your script, and make sure to set it to executable (chmod a+x scriptname.coffee):
#!/usr/bin/env coffee
path = require 'path'
fs = require 'fs'
...
At least that is how I launch executable coffeescript "scripts" at my end (a Linux system, but still...).
Choroba is correct.
But instead of using full directory paths you could also get the current directory programmatically so you don't have to hard code any paths.
#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
coffee -o $DIR/public/app/ -cwb $DIR/public/src/
When clicked, the script probably starts in a different folder. Use full paths in your script to make it universal.