python subprocess module stuck while executing a batch file - python

I am trying to learn to code using python on my own but I ran into a problem.
I am using python's subprocess module to execute a .bat file, but the process seems to get stuck at the bat file. The python code currently looks like this:
import getpass
username = getpass.getuser()
from subprocess import Popen
p = Popen("hidefolder.bat", cwd=r"C:\Users\%s\Desktop" % username)
stdout, stderr = p.communicate()
import sys
sys.exit()
And the .bat file looks like this:
if exist "C:\Users\%username%\Desktop\HiddenFolder\" (
attrib -s -h "HiddenFolder"
rename "HiddenFolder" "Projects"
exit
)
if exist "C:\Users\%username%\Desktop\Projects\" (
rename "Projects" "HiddenFolder"
attrib +s +h "HiddenFolder"
exit
)
if not exist "C:\Users\%username%\Desktop\HiddenFolder\" (
mkdir "C:\Users\%username%\Desktop\HiddenFolder\"
)
exit
Is there a way to kill the child process even if the python script is waiting for the child process to be terminated before continuing? Or is the problem in the child process to start with?
Thank you in advance.

You need to use subprocess.PIPE for stdout and stderr, or else they can't be fetched through Popen.communicate, and is the reason why your process is stuck.
from subprocess import Popen, PIPE
import getpass
username = getpass.getuser()
p = Popen("hidefolder.bat", cwd=r"C:\Users\%s\Desktop" % username, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
import sys
sys.exit()

I am a new programmer but i could solve my problem writting below code.
import subprocess
subprocess.call([r'ProcurementSoftwareRun.bat'])
print ('Software run successful')
My bat file was like:
#ECHO OFF
cmd /c start "" "C:\Program Files (x86)\UserName\ERPModule\PROCUREMENT.exe
exit

Related

Python program can't find Shellscript File

Hey i'm trying to run a shell Script with python using the Following lines:
import subprocess
shellscript = subprocess.Popen(["displaySoftware.sh"], stdin=subprocess.PIPE)
shellscript.stdin.write("yes\n")
shellscript.stdin.close()
returncode = shellscript.wait()
But when I run the Program it says that it can't find the .sh file.
Your command is missing "sh", you have to pass "shell=True" and "yes\n" has to be encoded.
Your sample code should look like this:
import subprocess
shellscript = subprocess.Popen(["sh displaySoftware.sh"], shell=True, stdin=subprocess.PIPE )
shellscript.stdin.write('yes\n'.encode("utf-8"))
shellscript.stdin.close()
returncode = shellscript.wait()
This method might be better:
import subprocess
shellscript = subprocess.Popen(["displaySoftware.sh"], shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
returncode = shellscript.communicate(input='yes\n'.encode())[0]
print(returncode)
When running this on my machine the "displaySoftware.sh" script, that is in the same directory as the python script, is successfully executed.

how to overcome pinentry of gpg using python when we run an gpg command in python script

I tried the following code which is working perfect, but it's not taking my passphrase. when I run this code I get a popup which asks to enter the passphrase for every time I run the python code in new cmd. But I want to automate this. So please suggest a better option to take passphrase for python script itself.
from subprocess import PIPE, Popen
output_file_name = 'abc.zip'
input_file_name = 'abc.zip.pgp'
args = ['gpg', '-o', output_file_name, '--decrypt', input_file_name]
proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE,shell=True)
proc.stdin.write('passphrase\n')
proc.stdin.flush()
stdout, stderr = proc.communicate()
print(stdout)
print(stderr)

Controlling shell stdin from python

I have a custom input method and I have a python module to communicate with it. I'm trying to control the shell with it so everything from local stdout is printed on the remote device and everything sent from the remote device goes into local stdin, so that remote device can control the input given to the program, like if there was an input function inside the program the remote device can answer to that too (like in ssh).
I used python subprocess to control the stdin and stdout:
#! /usr/bin/python
from subprocess import Popen, PIPE
import thread
from mymodule import remote_read, remote_write
def talk2proc(dap):
while True:
try:
remote_write(dap.stdout.read())
incmd = remote_read()
dap.stdin.write(incmd)
except Exception as e:
print (e)
break
while True:
cmd = remote_read()
if cmd != 'quit':
p = Popen(['bash', '-c', '"%s"'%cmd], stdout=PIPE, stdin=PIPE, stderr=PIPE)
thread.start_new_thread(talk2proc, (p,))
p.wait()
else:
break
But it doesn't work, what should I do?
p.s.
is there a difference for windows?
I had this problem, I used this for STDIN
from subprocess import call
call(['some_app', 'param'], STDIN=open("a.txt", "rb"))
a.txt
:q
This I used for a git wrapper, this will enter the data line wise whenever there is an interrupt in some_app that is expecting and user input
There is a difference for Windows. This line won't work in Windows:
p = Popen(['bash', '-c', '"%s"'%cmd], stdout=PIPE, stdin=PIPE, stderr=PIPE)
because the equivalent of 'bash' is 'cmd.exe'.

Calling a shell script from python

I have a python script that calls a shell scrips, that in turn calls a .exe called iv4_console. I need to print the stdout of iv4_console for debugging purposes. I used this:
Python:
import sys
import subprocess
var="rW015005000000"
proc = subprocess.Popen(["c.sh", var], shell=True, stdout=subprocess.PIPE)
output = ''
for line in iter(proc.stdout.readline, ""):
print line
output += line
Shell:
start_dir=$PWD
release=$1
echo Release inside shell: $release
echo Directory: $start_dir
cd $start_dir
cd ../../iv_system4/ports/visualC12/Debug
echo Debug dir: $PWD
./iv4_console.exe ../embedded/LUA/analysis/verbose-udp-toxml.lua ../../../../../logs/$release/VASP_DUN722_20160307_Krk_Krk_113048_092_1_$release.dvl &>../../../../FCW/ObjectDetectionTest/VASP_DUN722_20160307_Krk_Krk_113048_092_1_$release.xml
./iv4_console.exe ../embedded/LUA/analysis/verbose-udp-toxml.lua ../../../../../logs/$release/VASP_FL140_20170104_C60_Checkout_afterIC_162557_001_$release.dvl &>../../../../FCW/ObjectDetectionTest/VASP_FL140_20170104_C60_Checkout_afterIC_162557_001_$release.xml
exit
But this didn't work, it prints nothing. What do you think?
See my comment, best approach (i.m.o) would be to just use python only.
However, in answer of your question, try:
import sys
import subprocess
var="rW015005000000"
proc = subprocess.Popen(["/bin/bash", "/full/path/to/c.sh"], stdout=subprocess.PIPE)
# Best to always avoid shell=True because of security vulnerabilities.
proc.wait() # To make sure the shell script does not continue running indefinitely in the background
output, errors = proc.communicate()
print(output.decode())
# Since subprocess.communicate() returns a bytes-string, you can use .decode() to print the actual output as a string.
You can use
import subprocess
subprocess.call(['./c.sh'])
to call the shell script in python file
or
import subprocess
import shlex
subprocess.call(shlex.split('./c.sh var'))

How to execute a UNIX command in Python script

#!/usr/bin/python
import os
import shutil
import commands
import time
import copy
name = 'test'
echo name
I have a simple python scripts like the above. When I attempt to execute it I get a syntax error when trying to output the name variable.
You cannot use UNIX commands in your Python script as if they were Python code, echo name is causing a syntax error because echo is not a built-in statement or function in Python. Instead, use print name.
To run UNIX commands you will need to create a subprocess that runs the command. The simplest way to do this is using os.system(), but the subprocess module is preferable.
you can also use subprocess module.
import subprocess
proc = subprocess.Popen(['echo', name],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
(out, err) = proc.communicate()
print out
Read: http://www.doughellmann.com/PyMOTW/subprocess/

Categories