Run Python script as a standard CLI program - macos

How do I write a simple Python script that is globally executable via a simple command (such as cd or pwd)?
I know the file has to be executable and in my $PATH. I know I can omit the python prefix when calling the file by specifying the interpreter. But then I still have to call the script using the ./script syntax.
I basically want to create a bunch of Python CLI programs stored ~/bin and have them behaving the same way as Bash scripts like cd and pwd.

You just need to add ~/bin to your PATH. For example, you could add something like this to your ~/.bashrc file:
export PATH="$HOME/bin:$PATH"
To see the changes in the current shell, you can then do . ~/.bashrc. The path should automatically be added in all new shells that you open. You can check by doing echo "$PATH" - you should see that it starts with /home_directory/bin:....

Related

how can i make my bash script (.sh) to run locally as a bash command? [duplicate]

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.

How do I create new unix executable (.sh?) files for the terminal to use as commands?

I'd like to make some files to put in my /usr/bin folder (Mac OS) and be able to run them by typing the name to the terminal, like the commands gcc, cd, or vim (those are all in that folder). When I open such a file as text, it appears encrypted, so I'm not sure how to create one or what extension to use. Thank you.
The files you see in /usr/bin are not encrypted - they're compiled code in machine language different from bash scripts. You can however have scripts also in the /usr/bin location and have them run exactly as you are expecting.
In order to do that, you will have to create an executable script file. In unix, scripts are not identified by file extension but by 2 things:
executable bit set on the file permission level
Script interpreter header, such as #!/bin/bash
For a bash script, you can do the following:
Make a new file with the following content:
#!/bin/bash
echo "Hello world - My first bash script."
Save the file as hello.sh (the .sh is just convention, it could be any file name).
Then run chmod +x hello.sh and you will be able to run this file as an executable.
Move this file to /usr/local/bin and you should be able to run hello.sh from command line and it should execute your program.
You can create scripts, for example in bash, make the file executable with chmod and put the file path in your $PATH.
Example:
Create a new file called myscript.sh, you can use vi or any editor you prefer.
Add the content below on it:
#!/bin/bash
echo "Hello world!"
Now make it executable:
chmod u+x my script.sh
You can run your script like this ./myscript.sh or add it to your path:
export PATH=$PATH:$PWD
Now you can just run with the name, like myscript.sh
Programs such as gcc and cd are not encrypted, but compiled; however, if you create a shell script (without .sh as suffix; the .sh file extension for a shell script is optional) and place it in /usr/bin or any PATH location, and you chmod +x <script-path> (to give execute permission) then you can directly use that as a command.
Note: use shebang to mention the script interpreter, e.g. #!/usr/bin/env bash or equivalent for korn shell, python, etc.

How to run a shell script just by typing its name?

I am very stuck on a task for my controlled assessment. I have been asked to create a shell script in nano that echoes hello world and hello $user. I have set the script to be executable. (chmod 755 Script1 and chmod +x Script1). I have been tasked to be able to make the script run just by typing 'Script1' , I do not know how to set the path to do this. Any help would be greatly appreciated.
Basically you need to have it in the PATH environment variable.
Suppose it's in a folder on /a/b/folder/script.sh, try:
PATH=$PATH:/a/b/folder/
This tells the shell to look for executables there when looking for commands to run.
To make sure it's always executable you have several options:
Set the path variable in your profile using ~/.bashrc (sets it for bash, commonly done in ubuntu, which is what I use) or ~/.profile.
Set it globally using /etc/environment or others...
Move the folder to a folder already on your path (echo $PATH to see what's there already).
Note that these files are source-ed on different stages and persist on different environments.
For even more information read this.
TIP: To test that you've set the file correctly, we'll take ~/.bashrc as an example, you can use source ~/.bashrc and everything in ~/.bashrc will be loaded. That way you can be sure it won't mess things up next time you log in.
Alias the script in .bash_profile
in home path open the .bash_profile file and add the following entry,
alias Script1='/path/to/Script1'
Then reload the bash by,
. .bash_profile
After that try to call the script by using just its name. i.e, Script1

Converting a shell script to a dmg

I have a shell script with some functionalities. I want to convert it to an executable file. Any idea if this is possible?
Thanks
Add the following line at the very top of your script:
#!/bin/sh
This is known as a shebang. It indicates which program to invoke the shell script with when you execute it. You could change it to anything. Eg, to run a zsh script you would use #!/bin/zsh, which is the path to the zsh interpreter on my machine.
Then you need to mark the file as executable using chmod. You can do this as follows:
chmod +x myscript
You can now run the script like this:
/full/path/to/myscript
Or, if you're in the directory the script is in:
./myscript
The '.' expands to the path of your current working directory.
If you want to be able to run the script from anywhere, stick it somewhere in your path. Eg.
mv myscript /usr/bin
You can now run the script from anywhere by typing in just the name.

Run Ruby script without invoking it directly

I'm looking for solution how can run Ruby script without invoking it directly like
ruby /path/to/file.rb
So far, I have been using aliases in my .bashrc to create shortcut like
alias myscript='ruby /path/to/file.rb'
But now, I need to create a gem which I'd like to use on different computers and my current approach doesn't fit well for this.
What you could do is the following:
Create a shell script which invokes the Ruby script as your alias does:
ruby /path/to/file.rb
Set a softlink to the /usr/bin/ path to invoke it in the shell using somecommand:
ln -s /full/path/to/the/previously/created/shellscript /usr/bin/somecommand
If you wanna go further, you could create a shell script which does the soft-linking automatically.
Add a shebang to the beginning of the script
#!/usr/bin/env ruby
(check that shebang is #!)
then make your script executable
chmod +x file.rb
Now you can run the file as a "standalone" executable
# For example
$ ./file.rb
("Standalone", because the ruby interpreter still needs to be installed somewhere in your path.)

Resources