Windows Run can't find batch file - python

I created a very simple batch file that works when I double click the file, but if I try to launch it by typing in the name of the batch file into Windows Run, Windows is unable to find it. If I type in the name of the folder containing the batch file, the folder opens up.
Fairly new to coding. I'm going through "Automate the Boring Stuff" book

Run searches the folders in your global %PATH% variable for your file. It's unlikely that your script is in one of the directories mentioned in %PATH%.
To see the contents of PATH, type ECHO %PATH% into a command prompt. You can then move your script to one of the directories.
Alternatively, to temporarily (for the current CMD session) add a directory to PATH, run SET PATH=%PATH%;C:\path in your command prompt. A permanent change in PATH requires use of the registry.
I recommend you reconsider this approach however, as launching CMD then navigating to the script's location (CD C:\path) to then run the script is generally preferable to changing global variables.

Related

How to get path of current directory in Windows Batch/Python file?

The question may seem confusing and I am not a coding expert, so hopefully I can explain it properly...
I have a simple windows batch file that I use to run a python script. The batch file looks something like this:
cd C:\model\scripts
python run_project.py C:\2017to2021\Spruce2\button-down-president
So after changing directories to where they python script is saved, run_project.py initializes a hydrologic model that uses inputs from the path C:\2017to2021\Spruce2\button-down-president.
The thing is, I often have many different model runs set up, each with a unique path to the inputs. Normally I will just copy a stock version of this batch file directly to the path of a given run, then manually go in and update it with the new path name. So I would copy the example batch file above to a new directory and manually turn it into something like:
cd C:\model\scripts
python run_project.py C:\Documents\BAER_Roads\Modeling\Wepp_PEP\Runs\SingleStorm\NomeCreek
Doing it this way works well enough, but it is rather clunky and it's easy to make a mistake when updating to the new path name. I would love it if there was a way for the batch file to automatically update with the path to the directory where the file itself is saved. That way I could just paste the batch file in the directory of the new model inputs are, and it would without me having to manually open the file and copy/paste the new path name.
I'm not sure if this is something that the batch file could do all together before initializing python, or if python would have to somehow look back out at the path of the file that was used to initialize it? Maybe this isn't even possible to do at all? Maybe I have no idea what I'm talking about and should keep my 2-cents to myself?
Hopefully that explanation is relatively clear... Any help would be greatly appreciated. Maybe this is quite simple for someone that knows what they're doing. But if it isn't already obvious, I am not one of those people.
I would suggest following better solution.
First create a batch file with the following command lines:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Assign the folder path passed to batch file to environment variable FolderPath.
set "FolderPath=%~1"
rem Use the batch file path if started without a folder path argument.
if not defined FolderPath set "FolderPath=%~dp0"
rem Remove all double quotes from folder path.
set "FolderPath=%FolderPath:"=%"
if not defined FolderPath set "FolderPath=%~dp0"
rem Replace all slashes by backslashes in folder path.
set "FolderPath=%FolderPath:/=\%"
rem Make sure the folder path ends with a backslash.
if not "%FolderPath:~-1%" == "\" set "FolderPath=%FolderPath%\"
rem Check the existence of this folder and run Python on folder existing.
if exist "%FolderPath%" cd /D "C:\model\scripts" && python.exe "run_project.py" "%FolderPath%"
rem Restore the initial execution environment which includes the initial current directory.
endlocal
This batch file should be stored in one of the folders listed in environment variable PATH. Run in a command prompt window set path to get output the two environment variables PATH and PATHEXT used by cmd.exe to find executables like python.exe and scripts like the batch file with the command lines above.
Then the batch file can be run with just double clicking on it on being copied into the folder containing the files to process as well as from within a command prompt window with folder path as argument entered in a command prompt window, best with file/folder name completion as described by the usage help output on running cmd /? in a command prompt window.
But most useful would be right clicking on the batch file in its final folder and left clicking in context submenu Send to on menu item Desktop (create shortcut). Next the shortcut file created on userĀ“s desktop is selected, cut with Ctrl+X and pasted with Ctrl+V into the folder %APPDATA%\Microsoft\Windows\SendTo which expands usually to something like C:\Users\UserName\AppData\Roaming\Microsoft\Windows\SendTo.
This makes it possible to right click on any folder in Windows File Explorer and left click in opened context menu in submenu Send to on the name of the menu item according to name of the shortcut file to start the batch file with the full qualified folder name of the right clicked folder as first argument passed by Windows File Explorer to the batch file. So the batch file can be used for any folder without the need to copy around the batch file or entering the folder path manually in a command prompt window.
The batch file is fail safe as much as possible even on wrong usage from within a command prompt window on which a folder path is entered manually perhaps not correct as argument on running the batch file. The batch file can be also called from another batch file without affecting the parent batch file environment.
The command lines starting with rem can be removed as these are only remarks explaining the code.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~dp0 and %~1
cd /?
echo /?
endlocal /?
for /?
if /?
rem /?
set /?
setlocal /?
See also single line with multiple commands using Windows batch file for an explanation of operator && to run python.exe only if changing the current directory to C:\model\scripts was successful which should never fail, but who guarantees data for the future.
The question in my mind is, why do you bother cd'ing to the directory containing run_project.py?
Why do you think that is necessary? If you didn't do that, then it seems you wouldn't need the absolute path to the data file.
Just use
python C:\model\scripts\run_project.py button-down-president
Normally to avoid path problems for commonly executed items, one installs those items to a folder that is apart of your path. For example, if you open "Anaconda Prompt" and run the command "openssl" it runs without care about what directory you are at. This is because Anaconda installed openssl to a folder .../Anaconda3/Library/bin and added this path to the paths that your system looks for. You can do this yourself as well.
Create folder, say C:\Scripts.
Add said folder to your systems PATH or to your PYTHONPATH. Windows menu, RUN, type "systempropertiesadvanced", pops open the menu, click Environment Variables. You can now add another path if you like.
Drop your run_project.py file into the folder.
Open any terminal and type "python run_project.py" no matter where your terminals location is.
You can do this by putting the following in your batch file:
cd /d %~dp0
cd /d moves to the relevant directory, even if that directory is on another drive. The %~dp0 part expands to the directory of the script (see this answer for more details).
The other answer about using the PYTHONPATH environment variable is also a good way to do what you want.

How is git able to run C scripts in the current directory as a command on terminal?

I have been looking into bash and shell recently and been trying to work out how git is able to make a terminal command that runs C scripts in the current directory e.g git init, git push/pull etc.
I have been trying to simulate it in python, by making an executable python script in my home directory,
#!/usr/bin/env python
import os
print("current_dir: ",os.getcwd()) #prints /Users/usr/folder/script.py
Then I create a .command file that calls the python script
cd
cd FOLDER/
python3 SCRIPT.py
and editing the bash profile to export a variable to run the .command file.
export mycommand=/Users/urn/folder/command.command
Although this is not even nearly close to the way git achieves its command line. For example, when I run my script is not actually a terminal command it is just an environment variable, hence the $.
$mycommand
Secondly, this goes to the directory of the python file and runs the script from with that directory, therefore the output will always be the same
/Users/usr/folder/script.py
Although in git it runs the file in the current directory. Therefore the print statement would change depending on the terminal directory.
How am I able to create my own 'terminal command' such as git init to run my python script in whatever directory I'm in. Ps, I'm on mac.
Any help would be greatly appreciated :)
It sounds like you are missing at least two basic concepts:
The search path: when you issue a command that is not a shell function or built-in and that has an unqualified name (one with no / characters), the shell searches a list of zero or more directories for a matching executable file. This list of directories is the "path", and it is stored in the PATH environment variable. You can change it if you wish. This is how the shell finds the git program when you do not specify a path to it.
Executable scripts: Python, shell, Perl, etc. programs that must be run via an interpreter can be made executable by name alone by including an appropriate shebang line as the very first line and assigning an executable mode. You include an appropriate shebang line in your example Python program, in fact, but you seem not to understand its significance, because you explicitly launch the script via the python3 command. The shebang line is just another comment to Python, but it is meaningful to the system.
It seems like you probably also are missing some other concepts, like the fact that your script doesn't need to be in the current working directory for you to run it via the python3 launcher, path notwithstanding. Just specify its full pathname. Alternatively, Python has its own variation on a path, PYTHONPATH, by which it can locate modules and packages. These are alternatives, however -- the first two points are enough to achieve your apparent objective. Specifically,
Keep the shebang line in your script, though your default python is probably v2.7, so if you really want to run it specifically via python3 then modify the shebang line to say so:
#!/usr/bin/env python3
Make sure the file has executable mode. For example,
chmod 0755 /Users/urn/bin/SCRIPT.py
Then you should be able to execute the script from anywhere via its full pathname.
To access it from anywhere via its simple name, ensure that the directory containing it is in your path. For this purpose, it would be wise to choose an appropriate directory, such as /usr/local/bin or /Users/urn/bin (you may need to create the directory first). Whichever you choose, ensure that that directory is in your PATH. For example, edit /Users/urn/.bash_profile, creating it if necessary, and ensure that it contains (say) the commands
PATH=$PATH:/Users/urn/bin
export PATH
That will take effect in new Terminal windows you open afterward, but not automatically in any that are already open. In those windows, you will be able to run the script, from anywhere, via its simple name.

Python Directory organization

I've just started a class that uses Python. At this point, I'm a complete beginner. I running Windows 10 via Parallels on an iMac. I'm have trouble organizing the directories within the "Python36-32" directory that is located on the VM (Windows). If I place a .py file in the main directory, I can run the file through the command prompt and see something like.
c:\Program Files\Python36-32>python first.py
hello
However, if I try to organized the file the file isn't read at all. For example, if I wanted the "first.py" file to run from a "web221" (the name of my class) subdirectory of "python36-32" and then try to open "first.py", I get:
C:\Program Files\Python36-32\web221>python first.py
'python' is not recognized as an internal or external command,
operable program or batch file.
I'd really like to keep all of the .py files I create for my class organized for obvious reasons. Any help would be appreciated.
When you execute from the one directory, the Python executable is present and Windows has no issue finding what to execute.
From the other directory though, Windows attempts to find the executable in your PATH and cannot see it.
Here is some help from the Python 3 docs:
https://docs.python.org/3/using/windows.html#excursus-setting-environment-variables
Specifically, try this as a test:
Windows allows environment variables to be configured permanently at both the User level and the System level, or temporarily in a command prompt.
To temporarily set environment variables, open Command Prompt and use the set command:
C:\>set PATH=C:\Program Files\Python 3.6;%PATH%
C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib
C:\>python
However, this will only temporarily add the executable to your path. Try it to see if it works, and if it does, then you'll have the information you need to add it to your PATH variable permanently. Note: your directory is named differently, so you'll need to replace Python 3.6 with the name of the directory where Python is installed.
For the task of editing the PATH such that the changes persist from one command prompt session to the next, there's a related SO question that might be helpful:
How to add to the pythonpath in windows 7?

When using Python Windows Launcher, is there any way to prevent having to type full path?

In Windows 8, I often use the Python Windows Launcher like
py C:/long/long/long/long/long/path/to/prog.py ...
Is there any way to set some environment setting, such as PATH or PYTHONPATH etc, to prevent having to type the full path to prog.py?
From my basic knowledge/research, PATH only helps with the py part of the command line and PYTHONPATH only helps with imports within prog.py, so how do I deal with the path to prog.py itself??
Notes:
I cannot modify the code, not even the "shebang" line, since it is needed to work on other platforms.
I cannot cd to the directory containing the programs to run them, because the programs will do something based on the directory they're run in (they'll modify the files in the directory they're run in).
I know that if I associate .py extension with the Python Windows Launcher, then I can run prog.py as the first item in the command line, and thus use PATH, but currently my .py extension is associated with my favorite editor and I'd like to keep it that way if possible (so I can double-click any Python file in Windows Explorer and edit it).
However, if someone suggests a solution where I can have a different association for Windows Explorer versus the command line, then that could be a potential solution! (i.e. in Windows Explorer, .py opens with the editor, while on command line, .py runs with Python Windows Launcher)
Add your long path to PYTHONPATH, then invoke your program as such:
python -m prog
Python will search for a module called prog and then run it as the main module.
Answer to my own question: Actually, I'm so silly. I could just set a variable for each program path (there are only a few programs paths), i.e.. prog=C:/long/path/to/prog.py and then do py %prog% .... I guess I figured out an answer to my own question that was acceptable to me.
Update: I just found something even better. I can do
doskey prog=py C:/long/path/to/prog.py $*
and then simply prog ... afterward
Now I just have to do some crazy stuff to get the doskey command into a file that will be run every time I start a console, as described here: https://stackoverflow.com/a/21040825/5182136

Running Python in CMD not working

I am a Python beginner and I am having trouble running Python from CMD. I have added the Python installation directory as a PATH variable (;C:\Python27). I am able to run the Python Interpreter from CMD, however when I issue a command like "python file.py command" from CMD, it returns "Error2, Python can't open, no such file/directory".
So what I do is go to "cd C:\Folder\Folder2\My_Python_Files", then type the "file.py command" each and every time. Is there faster or more efficient way of doing this? I am currently running Python2.7 on Windows 8.
When you run python <script>, it requires an actual path to the script being provided. You cannot specify "file.py" alone, unless it is right there in your current directory.
In windows, here are two steps you can take:
Associate .py files with python. Then you can run them directly without the python command as: /path/to/file.py
(right click a .py -> properties -> change to associate with python.exe)
Further step: Add a location to your PATH environment which will contain your python scripts. From there, you can just do file.py and it will be found in your search path.
So you could add C:\Folder\Folder2\My_Python_Files to your PATH and that is where you can store your executable python scripts.
Also you can set the PATH variable temporarily during a shell session:
SET PATH=%PATH%;C:\path\to\project
Just like PATH environment variable lists several directories for the system to search for executables, the PYTHONPATH do the same for Python to search for .py files. If you want scripts in a folder to be globally accessible (i.e. you can reference them by name just like you want, or you can import them from other scripts), add that folder to PYTHONPATH (create it if it doesn't exist).
Note that the command to invoke a script that is in your PYTHONPATH is:
python -m file [<script arguments>]
(i.e. use the -m option to treat it as a module, and don't use the extension .py)
Here's an article explaining in more detail how Python finds its source files (both in the command line and through import).
Note that you can also refer to the script by using its full path:
python C:\Folder\Folder2\My_Python_Files\file.py command
But by doing this, other files in the same folder that this script might reference through import might not work (since Python doesn't know where to search for them).
Unless the project's folder is in the PATH, you cannot call the file unless you are inside the project's folder. Don't create PATHs for projects, unless they are needed; it's unnecessary.
Just transverse to the file's directory and run the command inside the directory. That will work.
If the project will be used by other projects/files, you can use PYTHONPATH to set the directory, so the other projects can successfully access it.
Hope that helps.

Categories