How to run a python script through command line? [duplicate] - python

This question already has an answer here:
How is git able to run C scripts in the current directory as a command on terminal?
(1 answer)
Closed 4 years ago.
I have been looking into bash and shell and have been trying to figure out how Git is able to run its C script in any directory. I have recently fiddled with environment variables, although this just redirects you to run a script in the location of that file, plus you have the $. How is Git able to integrate its scripts into the terminal? How would I be able to do the same with an arbitrary script in python?
It is really hard to find any information without knowing the correct terminology although here's my attempt of mimicking such a command line system as git.
I start with a command file in a folder in my home directory
something.command
Which on the inside directs me to a python script. e.g
cd
cd python_script_location
python3 script.py
Then I make this an environment variable through editing the .bash_profile.
export pyinit=/Users/Charlkie/vcscmd/pyinit.command
This although will just run a script in another directory. How can I make a terminal command that runs a python script in the current directory? Any help would be greatly appreciated :)

There is no requirement for scripts to switch working directories.
In fact, well-written scripts should, as a rule, not need to switch directories at all.
If the script requires access to a configuration file or something, a common set of arrangements is to allow the user to configure the file's location via an environment variable, then fall back to a system-wide standard location, and then fall back to the current directory, and as a last resort, perhaps examine the script's location via argv[0] (which is $0 in shell scripts).
In concrete terms, something.command should probably look like
exec python3 $HOME/python_script_location/script.py "$#"
... in which case you might as well make $HOME/python_script_location/script.py executable with a proper shebang (in this case usually #!/usr/bin/env python3) and maybe ln -s $HOME/python_script_location/script.py $HOME/bin (assuming $HOME/bin is already on your PATH) or maybe alias something.command=$HOME/python_script_location/script.py if you only need it interactively and don't otherwise have a directory in your PATH for your own personal scripts.

Add a symlink /usr/bin pointing at your script. Check this question how to do it: How to symlink a file in Linux?
Use which command to validate if the system can see it.

Related

Can't run Python script from Terminal without changing directories even though directory is included in PATH

OS: Mac 10.14.6
Python Version: 3.8.5
New to Python and Bash so apologies if this is a dumb question but I can't find an answer anywhere. The closest I found was this answer on this thread however, I've already executed chmod +x on that file to change the permissions to allow it to be executable and I followed the instructions again and I still couldn't get it to work.
Basically I want to run Python scripts from a specified folder on my desktop (file path ~/Desktop/Python\ Scripts) through Terminal without having to change directories (out of pure laziness).
I added the folder to PATH and can see that it is listed when I run echo $PATH in Terminal. I thought that would do the trick but when I try to run the program with the command python boxprintV2.py as I usually would when I change directories I get python: can't open file 'boxprintV2.py': [Errno 2] No such file or directory
This command works fine if I change the current directory as I have been doing and I can run my program no problem but I would like to run from a new terminal window without having to change directory every time. Permissions on the file have been changed using chmod +x
Shebang from my program is #!/usr/bin/env python3.
If you run the command python <filename>, the Python interpreter will only check the current directory. Therefore, this only works if your working directory is "~/Desktop/Python Scripts", as you have already found out.
Because your script is marked as executable and it includes a shebang at the beginning of the file, you can just execute it directly from the command line by only entering boxprintV2.py. Bash will then search all directories in $PATH for this file and execute it.
Ok, I've found a workaround by creating a shell script following this answer on a different thread.
What I did was open a blank textedit file, go to format and convert it to plain text (or ⇧ + ⌘ + T which toggles rich text/plain text).
From there I typed these commands into the document as follows:
#! /bin/bash
cd ~/Desktop/Python\ Scripts
python boxprintV2.py
When I saved I didn't specify a file extension and unticked the box that said "If no extension is provided, use .txt". I'm not sure if this was necessary but I'm just detailing my exact workflow for anyone else who may have the same (laziness) problem as I do.
I then went back into a blank terminal window and entered:
chmod +x ~/Desktop/Python\ Scripts/boxprintV2to allow the shell script to be executed by all users.
From here I can just open the Python Scripts folder on my desktop, double click on the plain text file which is now a .exe and a new terminal window is opened with my Python script running!
It's literally going to save me tens of seconds of my life. I'm sure I'll waste them anyway.

Run Python script with Automator // why does it only work if I include export PATH=/usr/local/bin:$PATH and what does it mean?

I was trying to run a Python script via Mac's Automator and the command is very straight forward:
"cd /Users/myname/Desktop/project && python3 myprojectapp.py".
However, every time I tried to run it, Automator raised an error such as ModuleNotFoundError. This was however, impossible since I had all libraries (e.g. Pandas) installed and running the command in the Terminal as written above worked flawlessly.
Now, I've read somewhere for a similar problem to just include:
"export PATH=/usr/local/bin:$PATH" before the command and it worked. Now, before I go on with my life, I would like to understand what exactly this extra line does and how it affects Automator to the point of making the script work.
Thank you in advance!
That command basically modifies the environment variable PATH and puts the directory /usr/local/bin before everything that is currently in PATH. However, that command is temporary, and the environment variable PATH is restored when the session closes.
What could be happening is the python you're running in terminal and the python Automator is running are different./usr/local/bin probably contains the same python version as you are using in terminal. Take a look at ~/.bash_profile to see if something similar to export PATH=/usr/local/bin:$PATH is in there.
Another way to check is to type which python in both and see if it points to the same python. You probably have yet another python somewhere in the list of directories in your PATH variable.
It's common to use virtual python environments to keep track of which python is running and to experiment with python without messing with system python. Examples of these include: Anaconda and virtualenv.

Writing a command line app

I am in Ubuntu 16.4. I have just written a program that can be executed using the command(assuming i'm in the correct directory) ./Main.py -h
However I want this to be distributable, so that you can use it from the command line like nmap or youtube-dl. My idea was to put an alias is .bashrc. This had two problems. One was that I couldn't have the options(-h) in the command if there was a command after it, so it changed your directory. Second I don't know what directory the users would install it in. So even if I appended the alias to .bashrc I wouldn't know what directory it was installed in. I tried to fix this issue by copying the files to their home directory but this gave me an error that said Permission Denied(while running the program) as it needs to be able to write to files. I tryed for a while to fix this but in the end they needed to run it as root and that shouldn't be necessary. So how should I install this so that it can be used like a regular command line tool?
Normal convention for command line programs is to place them on the default path, which is to say in one of the directories represented by the $PATH environment variable. There is also a default on various systems.
This way, when you enter a command, your shell will attempt to find a match in one of these directories, and you can omit the ./ part of the invocation.
Try the command echo $PATH to see what the path directories are on your particular system. /usr/local/bin is usually a good choice for a custom script.
Since you are using Python, you will also want to set it up as an executable script, which is a pretty common thing to do.
Good luck!

How to execute a python command line utility from the terminal in any directory

I have just written a python script to do some batch file operations. I was wondering how i could keep it in some common path like rest of the command line utilities like cd, ls, grep etc.
What i expect is something like this to be done from any directory -
$ script.py arg1 arg2
Just put the script directory into the PATH environment variable, or alternatively put the script in a location that is already in the PATH. On Unix systems, you usually use /home/<nick>/bin for your own scripts and add that to the PATH.
Add the directory it is stored in to your PATH variable? From your prompt, I'm guessing you're using an sh-like shell and from your tags, I'm further assuming OS X. Go into your .bashrc and make the necessary changes.
An alternative approach is to create a python package with entry points and install the program, rather than changing $PATH (using setuptools in setup.py). This has some advantages:
Works outside of shells
Reduces the amount of system-wide configuration, or at least puts it all in side the package.
See Explain Python entry points? and python: simple example for a python egg with a one-file source file? for details.
This has the advantage of keeping all your settings in one place.
You can use the --develop option so that you can still edit your code in place and the --user option to avoid messing python for other users.

How to import modules from alternate locations when using Python IDLE?

I've been trying to figure this out for more than 2 days, screening the internet and the tutorial, but yet I don't have solved my problem. I'm a real newb and don't yet really know what I'm doing..
Software I use:
Mac OS X 10.6
Python v3.2.2
Interactive interpreter (IDLE)
Problem:
IDLE's default directory is /Users/ME/Documents/. Files with the extention .py can only be opened when located in this directory. However, I made a folder where I would like to save all the .py files etc that have to do with this software. Currently, IDLE cannot load .py files from the chosen directory by me.
What I did first was I added to IDLE:
import sys.
sys.path.append('Users/Mydir/')
sys.path
However, in an already existing thread from 2010 I read sys.path is for the Interpreter ONLY, and that if I am to change this I need to modify the PYTHONPATH environment variable:
PYTHONPATH="/Me/Documents/mydir:$PYTHONPATH"
export PYTHONPATH
However, I'm confused how to use this and cannot find answers to my following questions:
1) PYTHONPATH (.py?) is already existing on my computer when I installed the program?
If YES, where is it? I cannot find it anywhere.
If NO, I need to create one. But where and what should be the content so that IDLE can load files from a non-default directory? Should it contain only the words in bold?
I hope I made my problem clear.
Cheers
It's not totally clear to me what you mean by load. That could mean Open and Close files in the IDLE editor. Or it could mean being able to use the Python import statement to load existing Python modules from other files. I'll assume the latter, that by load you mean import.
There are two general ways to launch IDLE on Mac OS X. One is from the command line of a terminal session; if you installed Python 3.2 using the python.org installers, by default typing /usr/local/bin/idle3.2 will work. The other way is by launching IDLE.app from /Applications/Python 3.2, i.e. by double-clicking its icon. Because you say the default directory for files is your Documents folder, I'm assuming you are using the second method because IDLE.app sets Documents as its current working directory, which becomes the default directory for *Open*s and *Save*s and is automatically added as the first directory on Python's sys.path, the list of directories that Python uses to search for modules when importing.
If you want to add other directories to sys.path, as you've noted you can use the PYTHONPATH environment variable to do so. The standard way to do this is to add an export PYTHONPATH=... definition to a shell startup script, like .bash_profile. However, if you use IDLE.app, no shell is involved so commands in .bash_profile have no effect.
While there are ways to modify the environment variables for OS X GUI apps, in this case, a simpler solution is to use the other method to invoke IDLE, from the command line of a shell session, using either /usr/local/bin/idle3.2 or, if you've run the Update Shell Profile command in the /Applications/Python 3.2 folder (and opened a new terminal session), just idle3. Then, a PYTHONPATH environment variable you set up will be inherited by that IDLE.
BTW, there is no direct way to modify the initial current working directory of IDLE.app from Documents other than modifying the code in IDLE. If you start IDLE from a command
line, it inherits the current working directory of the shell.
[UPDATE] But rather than fooling around with defining PYTHONPATH, here is another even simpler, and probably better, approach that should work with either IDLE.app or the command line idle. It takes advantage of Python path configuration (.pth) files and user site-package directories. Assuming you are using a standard Python framework build of 3.2 (like from a python.org installer) on Mac OS X, create a path file for the directory you want to permanently add to sys.path. In a terminal session:
mkdir -p ~/Library/Python/3.2/lib/python/site-packages
cd ~/Library/Python/3.2/lib/python/site-packages
cat >my_paths.pth <<EOF
/Users/YOUR_USER_NAME/path/to/your_additional_python_directory_1
/Users/YOUR_USER_NAME/path/to/your_additional_python_directory_2
EOF
Now, whenever you run that Python 3.2 or IDLE under your user name, the directories you have added to the .pth file will automatically be added to sys.path.
BTW, the exact path location of the user site-packages directory for versions of Python earlier than 3.2 or 2.7 may be slightly different. Also, on other Unix-y systems, the default location for the user site-package directory is ~/.local/lib/python3.2/site-packages.
PYTHONPATH is an environment variable (see here and here). I don't have a Mac, but from the threads I have linked to you would type something like
launchctl setenv PYTHONPATH=/Me/Documents/mydir:$PYTHONPATH
on the command line to allow you to run Python scripts from /Me/Documents/mydir. Alternatively, put this line in a file called .bashrc in your home directory (~) and this path will be set each time each time you open a terminal. See here for a short introduction to .bashrc and other .bash* files. Hope that helps.
EDIT See also this question.

Categories

Resources