I'm working on a script which should run a command in a new subprocess. At the moment im using the python subprocess.Popen() for this. My problem is that I can run commands like "dir" but not a installed program. When I open the cmd prompt and write "program -h" I am getting the normal help outprint. When I try to open it with Popen() I am getting an error that the program can not the found. It is like he is not finding the executable even if the cmd promt can find it when I look for it manually. For the test i used ncat as an example program.
import time
from subprocess import *
import subprocess
execom = "ncat -h" # DOES NOT WORK IN PYTHON BUT MANUALLY IN CMD
execom1 = "ncat -h -e cmd" # DOES NOT WORK IN PYTHON BUT MANUALLY IN CMD
execom2 = "dir" # WORKS
p = Popen(execom, shell=True)
out = p.communicate()[0]
Does someone know how to fix that?
EDIT:
I got the solution with the hint of 2e0byo. I added the paths to the systemvariabels but the system needed an extra restart to pass it. It worked without restart from cmd prompt but not from python script. After restart it works from both now.
Per the comments, the problem is just that ncat isn't in your PATH, so you need to add it:
import os
env = os.environ.copy()
env["PATH"] = r"C:\Program Files (x86)\Nmap;" + env["PATH"]
p = Popen(execom, env=env)
...
See this question for modifying the env.
As to why ncat isn't in your path I really don't know; I don't use Micro$oft Windoze very much. Perhaps someone will be along with a canonical answer to that question, or you can ask it over on superuser and see if someone knows how to set it up. If I needed this to be portable I would just check a bunch of folders for ncat and bail if I couldn't find it.
Related
I have been trying to figure out a way to run Powershell commands inside a Pycharm project where I can make more complicated scripts using Python. I have been searching for an answer but I have only found a few people even ask this question.
I have already verified that my Terminal inside Pycharm is set to PowerShell.
Is there a way to combine a Powershell command inside Python?
If so is there a way to do this inside Pycharm?
I was able to research more about the subprocess module and I was able to find a way to do this inside a python project. Below I put a snippet of a very simple command ran with powershell that outputted what I expected so I can add to that.
import subprocess, sys
computer_name = "L8694C"
p = subprocess.Popen(
["powershell.exe", "Get-ADComputer " + computer_name+ " | Select-Object Name"],
stdout=sys.stdout)
p.communicate()
Basically what I'm looking to do is to have python code that I can run from cmd that opens a new cmd window then types commands into it. I have been able to open and run commands but the commands always run in the first cmd window. I think I might need to switch the cursor or something like that, but I don't know how.
Here is my current code.
import subprocess
subprocess.call('start', shell=True)
import time
time.sleep(5)
cmd=['', ''] ### In the second '' you can type in cmd.
for each in cmd:
process=subprocess.Popen(each,stdout=subprocess.PIPE,shell=True)
output=process.communicate()[0]
print(output.decode('utf-8'))
- Thanks
EDIT :
NVM Its in the similar one
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.)
I am not even sure if this question is answerable.
Basically in my game I am using the colorama features to make it look nice, but the colorama features only work when you access python in command prompt, so my question is how I can get python program to run another via command prompt, is this doable or not? I have tried installing win32 but that is in python 2 format and I am using 3.4 so I was getting syntax errors that I wasnt sure how to fix.
I am not sure why is this happening, I mean, colorama not working without starting from prompt.
Perhaps something with environment variables PATH or something.
This is one suggestion, and I am not sure that it will work as we will not be changing the window program is running in, just invoking cmd.exe i.e. command prompt to start within it and start python and your script again.
But it is worth a try:
# Start of your program:
import sys, os
if "started_with_prompt" not in sys.argv:
cmd = 'cmd /C "'+sys.executable+' '+" ".join(sys.argv)+' started_with_prompt"'
os.system(cmd)
sys.exit()
print "the rest of your program"
If this doesn't work, there are tricks that can be used through subprocess module to do the similar thing.
Also, you should look at cmd.exe's help to see whether you should use some other switch than /C to enable environment and/or registry extensions.
But, essentially, you should be able to get the same result by making a shortcut with the command like one in cmd variable, or a batch file that starts Python. Like this:
#echo off
cmd /C "C:\Python27\python.exe path_to_your_script.py"
I think both would work, but somehow that you wouldn't like this solution.
Well, I think that shortcut would need a full path to cmd.exe which is:
C:\Windows\system32\cmd.exe
Let me know if it doesn't work.
I'm working on windows vista, but I'm running python from DOS command. I have this simple python program. (It's actually one py file named test.py)
import os
os.system('cd ..')
When I execute "python test.py" from a Dos command, it doesn't work.
For example, if the prompt Dos Command before execution was this:
C:\Directory>
After execution, must be this:
C:\>
Help Plz.
First, you generally don't want to use os.system - take a look at the subprocess module instead. But, that won't solve your immediate problem (just some you might have down the track) - the actual reason cd won't work is because it changes the working directory of the subprocess, and doesn't affect the process Python is running in - to do that, use os.chdir.
I don't really use Windows, but you can try cmd /k yourcommandhere. This executes the command and then returns to the CMD prompt.
So for example, maybe you can do what you want like this:
subprocess.call(['cmd', '/k', 'cd .. && prompt changed'])
As I said, I am not familiar with Windows, so the syntax could be wrong, but you should get the idea.
In case you don't know, this is a different CMD instance than the one you were in before you started your python script. So when you exit, your python script should continue execution, and after it's done, you'll be back to your original CMD.