bat script under python subprocess lost ability to write to file - python

I'm learning to use the subprocess module.
I'm trying to run a .bat script under subprocess. The .bat script writes to a file every time it's called by double-clicking, but won't write to the same file when called from subprocess.
It's similar to this question, but in my case I'd much rather adapt the caller python script then the callee .bat script. The .bat is what I'm about to test.
My code follows. Path and name altered for brevity.
import subprocess
p=subprocess.Popen(r"path\foo.bat", shell=True, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
p.communicate(input='\r\n')
I will need to fill in user input as the .bat runs, so (I think) I need to call Popen directly rather than using convenience functions. But other than that direct call I think the issue is not related, because the file writing should occur before the .bat's first need for user input.
Ommitting the communicate call or each of the arguments to Popen were tried and failed.
How can I change my python script to give the .bat file-writing privileges?
The obvious security implications are not relevant to my use case, the .bat is trusted.
EDIT: when implementing Rptk99's suggestion I've noticed that I can replace the path to the .bat with any string (literally, I've tried "hjklhjilhjkl"), and I'll get the same behaviour: the python prompt becomes interactive again. So I have a more fundamental problem: I cannot see any errors returned from the call.

Related

Python execute code in parent shell upon exit

I have a search program that helps users find files on their system. I would like to have it perform tasks, such as opening the file within editor or changing the parent shell directory to the parent folder of the file exiting my python program.
Right now I achieve this by running a bash wrapper that executes the commands the python program writes to the stdout. I was wondering if there was a way to do this without the wrapper.
Note:
subprocess and os commands create a subshell and do not alter the parent shell. This is an acceptable answer for opening a file in the editor, but not for moving the current working directory of the parent shell to the desired location on exit.
An acceptable alternative might be to open a subshell in a desired directory
example
#this opens a bash shell, but I can't send it to the right directory
subprocess.run("bash")
This, if doable, will require quite a hack. Because the PWD is passed from the shell into the subprocess - in this case, the Python process, as a subprocess owned variable, and changing it won't modify what is in the super program.
On Unix, maybe it is achievable by opening a detachable sub-process that will pipe keyboard strokes into the TTY after the main program exits - I find this the most likely to succeed than any other thing.

Persistent Terminal Session in Python

I may not at all understand this correctly, but I am trying to allow a Python program to interface with a subprocess that runs commands as if on a Linux shell.
For example, I want to be able to run "cd /" and then "pwd later in the program and get "/".
I am currently trying to use subprocess.Popen and the communicate() method to send and receive data. The first command, sent with the Popen constructor, runs fine and gives proper output. But I cannot send another command via communicate(input="pwd").
My code so far:
from subprocess i
term=Popen("pwd", stdout=PIPE, stdin=PIPE)
print(flush(term.communicate()))
term.communicate(input="cd /")
print(flush(term.communicate(input="pwd")))
Is there a better way to do this? Thanks.
Also, I am running Python 3.
First of all, you need to understand that running a shell command and running a program aren't the same thing.
Let me give you an example:
>>> import subprocess
>>> subprocess.call(['/bin/echo', '$HOME'])
$HOME
0
>>> subprocess.call(['/bin/echo $HOME'], shell=True)
/home/kkinder
0
Notice that without the shell=True parameter, the text of $HOME is not expanded. That's because the /bin/echo program doesn't parse $HOME, Bash does. What's really happening in the second call is something analogous to this:
>>> subprocess.call(['/bin/bash', '-c', '/bin/echo $HOME'])
/home/kkinder
0
Using the shell=True parameter basically says to the subprocess module, go interpret this text using a shell.
So, you could add shell=True, but then the problem is that once the command finishes, its state is lost. Each application in the stack has its own working directory. So what the directory is will be something like this:
bash - /foo/bar
python - /foo
bash via subprocess - /
After your command executes, the python process's path stays the same and the subprocess's path is discarded once the shell finishes your command.
Basically, what you're asking for isn't practical. What you would need to do is, open a pipe to Bash, interactively feed it commands your user types, then read the output in a non-blocking way. That's going to involve a complicated pipe, threads, etc. Are you sure there's not a better way?

Executing some simple command in Command prompt using Python

I need to execute the simple command below in windows 7 command prompt using Python26.
cd C:\Python26\main project files\Process
C:\Aster\runtime\waster Analysis.comm
It runs a FEM simulation and I tried it manually and it worked well. Now, I want to automate the write procedure using Python26.
I studied the other questions and found that the os.system works but it didn't. Also I saw subprocess module but it didn't work.
The current directory is a process property: Every single process has its own current directory. A line like
os.system("cd xyz")
starts a command interpreter (cmd.exe on Windows 7) and execute the cd command in this subprocess, not affecting the calling process in any way. To change the directory of the calling process, you can use os.chdir() or the cwd keyword parameter to subprocess.Popen().
Example code:
p = subproces.Popen(["C:/Aster/runtime/waster", "Analysis.comm"],
cwd="C:/Python26/main project files/Process")
p.wait()
(Side notes: Use forward slashes in path names in Python files. You should avoid os.system() and passing shell=True to the function in the subprocess module unless really necessary.)

Cannot make consecutive calls with subprocess

I'm having trouble using mutilple subprocess calls back to back.
These 2 work fine:
subprocess.call(["gmake", "boot-tilera"], cwd="/home/ecorbett/trn_fp")
p = subprocess.Popen(["gmake", "run-tilera"], stdout=subprocess.PIPE, cwd="/home/ecorbett/trn_fp")
However, I get an error when I try to run this call directly after:
time.sleep(10)
subprocess.call(["./go2.sh"], cwd="/home/ecorbett/trn_fp/kem_ut")
I added sleep in there because I need a few seconds before I run the "./go2.sh" program. Not sure if that is the issue.
Any advice?
A possible reason why your shell script is working on the command-line is that the shebang line was not written correctly (or not written at all). See an example in which the script would work from a command line but not as a Python subprocess: Is this the right way to run a shell script inside Python?
If your shell script did not have a shebang line specified, it would work from command line because $SHELL is set in your environment and the script is taking that as a default. When running from a python subprocess, python does not know what it is and fails with OSError: [Errno 8] Exec format error. The subprocess.call() to gmake worked because it is a binary program and not a shell script. Using the argument shell=True gave an instruction to interpret the argument exactly as it would in a shell.
However, be careful about using shell=True in subprocess.call() as it may be insecure in some cases: subprocess Python docs.

Python 2.4.6 subprocess is befuddling me

I have written a nice python script that parses XML and adds some sophisticated logic to then interface with an external command via subprocess module.
Most of the subprocess.Popen calls do exactly what they're supposed to, but the last one simply refuses to execute. No error message , it just doesn't do what it's supposed to. I even put the actual CMD into a shell script surrounded by debugging statements, and the shell script gets executed, but not the actual CMD.
More infuriatingly, the very same line of code in a separate .py file executes just fine.
I have no idea why or how this could be?
The python code is generating a file and tries to invoke the external command with options
p = subprocess.Popen([CMD,'object','new_host','--file','/tmp/add.1234'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
r = p.communicate()
print r
this logic works in the standalone file, but not in the larger python script (which has other working Popen calls in it).
Does anybody have an idea why this could be?
PS: I can not update python to a more recent version

Categories