I am new to Python, could someone please let me know if we can register our python script to work as one of the command of cmd.exe, I am not asking about parsing or accepting command line arguements using argparse, etc..
Lets say I have a SearchDir.py file, to run it from cmd prompt I have to do "python SearchDir.py", so is there any way to simply do "SearchDir" and it should act as one of the command of cmd.exe
Yes, it is possible (if I have understood you correctly. The question was a bit unclear)
The first thing you need to do is to add a shebang to the top of your script: https://en.wikipedia.org/wiki/Shebang_(Unix). I see you mentioned cmd.exe so I assume you need this to work on Windows? In that case you should read https://docs.python.org/3/using/windows.html#shebang-lines as well
On unix hosts, the second thing we need to do is set our file as executable with chmod +x <filename>. I try to stay away from Windows, but from what I remember this is not relevant on Windows.
Last you need to place the script in a folder referenced by your $PATH-variable
The script will now be accessible as SearchDir.py from cmd.exe or a unix shell. If you want to omit the ".py"-part you simply rename the file to just "SearchDir"
Related
Excuse the awkward question wording.
I've made a script. I would like for others to download it from github, and run it by typing programName argument1 argument2, similar to any other popular app used through the terminal such as Jupyter or even opening Atom/Sublime/etc. (ex:jupyter notebook, atom .). However, unlike Jupyter or sublime, my script isn't launching another app, it's a small app meant to be used in the shell.
Currently, to use my script, one must type into the command line python programName.py arg1 etc from within the file's directory.
How do I allow others to dl it and use it from anywhere (not having to be within the directory), without having to type out the whole python programName.py part, and only having to type programName arg1?
This blog post explains step by step how to create a distribution that you can install and it would turn into an executable.
You can refer to this github repo for a sample application.
The full documentation of setuptools is available here.
In general, you should configure your setup.py in order to use the command in the entry-point option:
setup(
name = "your_app_name",
packages = ["package_name"],
entry_points = {
"console_scripts": ['cmd_name = package_name.package_name:main']
},
....
)
This solution would work on every OS where you have installed python.
Your script may need to have an interpreter, "shebang", besides being "reachable" by the $PATH
#!interpreter [optional-arg]
For example, you could have something like
#!/usr/bin/env python
or to force a specific version
#!/usr/local/bin/python2.7
Next, your script needs to be available within the $PATH, check this answer that covers that part: https://unix.stackexchange.com/q/29608/53084
You can simply add your script to PATH variable in order to launch it from anywhere.
In Linux distros, you can simply do it by using a bash command PATH=$PATH:/path/to/your/script.
Make sure you don't have the space around the "=" operator.
Now, the second thing is you don't want your script to be named as pythonProgram.py.You can simply remove the extension .py from PythonProgram.py by adding a single line to the starting of your script.
Open up your script and at the very begining type #!/usr/bin/python.This should be the first line of your code.This line is called shebang and is used to tell the bash which interpreter to be used for compiling the script.
If everything went right, you will be able to run your script as pythonProgram arg1.
In addition to mabe02: Python is a scripting language and usually not compiled, which means you will need an interpreter to run your program.
Programms made in C f.e. can be run on its own because they were compiled into machine code by a compiler.
An interpreter is similar to a compiler as it reads your script and interprets it at runntime. That is why you need to write python before your programm, to tell your computer to interpret your script on runntime, using python. This doesn't mean that there are no possibilities to compile python as can be seen in the other answer and in this link Can a python program be run on a computer without Python? What about C/C++? (py2exe and py2app).
I am trying to write a python script that will execute a bash script I have on my Windows machine. Up until now I have been using the Cygwin terminal so executing the bash script RunModels.scr has been as easy as ./RunModels.scr. Now I want to be able to utilize subprocess of Python, but because Windows doesn't have the built in functionality to handle bash I'm not sure what to do.
I am trying to emulate ./RunModels.scr < validationInput > validationOutput
I originally wrote this:
os.chdir(atm)
vin = open("validationInput", 'r')
vout = open("validationOutput", 'w')
subprocess.call(['./RunModels.scr'], stdin=vin, stdout=vout, shell=True)
vin.close()
vout.close()
os.chdir(home)
But after spending a while trying to figure out why my access was denied, I realized my issue wasn't the file permissions but the fact that I was trying to execute a bash file on Windows in general. Can someone please explain how to execute a bash script with directed input/output on windows using a python script?
Edit (Follow up Question):
Thanks for the responses, I needed the full path to my bash.exe as the first param. Now however, command line calls from within RunModels.scr come back in the python output as command not found. For example, ls, cp, make. Any suggestions for this?
Follow up #2:
I updated my call to this:
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
The error I now get is /usr/bin/bash: RunModels.scr: No such file or directory.
Using cwd does not seem to have any effect on this error, either way the subprocess is looking in /usr/bin/bash for RunModels.scr.
SELF-ANSWERED
I needed to specify the path to RunModels.scr in the call as well as using cwd.
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'C:\\path\\dir_where_RunModels\\RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
But another problem...
Regardless of specifying cwd, the commands executed by RunModels.scr are throwing errors as if RunModels.scr is in the wrong directory. The script executes, but cp and cd throw the error no such file or directory. If I navigate to where RunModels.scr is through the command line and execute it the old fashioned way I don't get these errors.
Python 3.4 and below
Just put bash.exe in first place in your list of subprocess.call arguments. You can remove shell=True, that's not necessary in this case.
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'],
stdin=vin, stdout=vout,
cwd='C:\\path\\dir_where_RunModels\\')
Depending on how bash is installed (is it in the PATH or not), you might have to use the full path to the bash executable.
Python 3.5 and above
subprocess.call() has been effectively replaced by subprocess.run().
subprocess.run(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'],
stdin=vin, stdout=vout,
cwd='C:\\path\\dir_where_RunModels\\')
Edit:
With regard to the second question, you might need to add the -l option to the shell invocation to make sure it reads all the restart command files like /etc/profile. I presume these files contain settings for the $PATH in bash.
Edit 2:
Add something like pwd to the beginning of RunModels.scr so you can verify that you are really in the right directory. Check that there is no cd command in the rc-files!
Edit 3:
The error /usr/bin/bash: RunModels.scr: No such file or directory can also be generated if bash cannot find one of the commands that are called in the script. Try adding the -v option to bash to see if that gives more info.
A better solution than the accepted answer is to use the executable keyword argument to specify the path to your shell. Behind the curtain, Python does something like
exec([executable, '-c`, subprocess_arg_string])
So, concretely, in this case,
subprocess.call(
'./RunModels.scr',
stdin=vin, stdout=vout,
shell=True,
executable="C:/cygwin64/bin/bash.exe")
(Windows thankfully lets you use forward slashes instead of backslashes, so you can avoid the requirement to double the backslashes or use a raw string.)
So, I am trying to run a Shell script from Python and I double checked that the location of the script.sh is all correct (because when I run it from sublime, the script.sh opens). What I have to call script.sh is:
subprocess.call("script.sh", shell=True)
When I run that, the function returns 0. However, the script is supposed to create a file in my folder and write into it, which it is not doing. It does work when I run the script from cygwin command prompt.
What could be wrong?
Please ensure you have added:
!/bin/bash
as the first line and also make sure that the file script.sh has executable permission.
chmod u+x script.sh
then try specifying the complete path:
subprocess.call("/complete/path/script.sh", shell=True)
At the top of your shell script somewhere, put the line:
pwd >/tmp/mytempfile
and then run the Python script and go look into that file.
This will let you find out the working directory of your scripts which, in the majority of cases where a file doesn't appear to be created, is different to what you think it should be.
You may also want to check the shell script to ensure it's not changing the working directory before creating the file but that would be unlikely given you've stated it works okay from the command line.
If you add the line to create the temporary file and it doesn't actually get created, then your script is not executing.
In that case, you could try a few things. The first is to fully specify the script on the off chance that Python isn't in the correct directory. In other words, something like:
subprocess.call("/actual/path/to/script.sh", shell=True)
Or you could try to run the actual bash executable with the script as an argument:
subprocess.call("bash -c script.sh", shell=True)
Yes, I know I can do
python2 cal.py
What I am asking for is a way to execute it on the command line such as:
calpy
and then the command afterwards. I put in in a path and when I write cal.py in the command line:
/usr/bin/cal.py: line 5: print: command not found
I don't want to issue cal.py to run my script, I want it to be issued with calpy
I'm running Arch Linux if that helps, thanks. Sorry for my English.
In order for bash to know to run your script via the Python interpreter, you need to put an appropriate shebang at the start. For example:
#!/usr/bin/python
tells bash to run /usr/bin/python with your script as the first argument. I personally prefer
#!/usr/bin/env python
which is compatible with virtualenv. You also need to ensure that the permissions on your script allow it to be executed:
~$ chmod +x path/to/cal.py
Finally, in order to call cal rather than path/to/cal.py, you need to remove the .py extension and make sure that the directory containing cal is in your command search path. I prefer to add ~/bin to the search path by modifying the $PATH environment variable in ~/.bashrc:
export PATH=$HOME/bin:$PATH
then put my own executables in ~/bin. You could also copy (or symlink) cal to one of the system-wide binary directories (/bin or /usr/bin), but I consider it bad practice to mess with system-wide directories unnecessarily.
Ok, you need a couple of things for achive what you want.
First you have to tell your script "How" is going to execute/interpret it. You can do this writting
#/usr/bin/env python
at the very beggining of the file.
The problem you have is the system is trying to execute the script using bash. And in bash there is no print command.
Second you need give execution privileges to your script. And of course if you want to call your script through the command "calcpy", the script has to be called like that.
Put this (exactly this) as the first line of your script:
#!/usr/bin/env python
I have written a very simple command line utility for myself. The setup consists of:
A single .py file containing the application/source.
A single executable (chmod +x) shell script which runs the python script.
A line in my .bash_profile which aliases my command like so: alias cmd='. shellscript' (So it runs in the same terminal context.)
So effectively I can type cmd to run it, and everything works great.
My question is, how can I distribute this to others? Obviously I could just write out these instructions with my code and be done with it, but is there a faster way? I've occasionally seen those one-liners that you paste into your console to install something. How would I do that? I seem to recall them involving curl and piping to sh but I can't remember.
Upload your script to something like ideone. Then tell your friend to pipe it into python. Example script:
def print_message():
print "This is my very special script!"
if __name__ == "__main__":
print_message()
Example of running script:
username#server:~$ curl http://ideone.com/plain/O2n3Pg 2>/dev/null | python
This is my very special script!
chmod +x cmd.py
then they can type ./cmd.py
they can also use it piped.
I would add that unix users would probably already know how to make a file executable and run it, so all you'd have to do is make the file available to them.
Do make sure they know what version(s) of python they need to run your script.