I'm calling subprocess.run to execute an external program outside. However the program requires administrative rights, I run the program using administrator but the python console prompts me for a password, but doesn't let me input the password and exits the program.
I've tried using subprocess.popen and subprocess.call, I've also tried running the program without administrative rights but pycharm will throw me a operation requires elevation error.
def runExecutables():
directory = r"C:\Users\Billy\Desktop\SURVEY_PROGRAM_WINDOWS_ENGLISH.exe"
#subprocess.Popen(directory)
subprocess.run(['runas', '/user:Administrator', directory])
#prog.stdin.write(b'password')
#prog.communicate()
I should be expecting, either the executable to run, or a prompt that pops up asking for the password to be inputted, proving to me that the executable is indeed being run. I am just getting a python prompt to enter the pass for administrator and it does not wait for me to enter the password before finishing the process.
With Popen, you have to pipe in stdin and flush the input
import subprocess
p = subprocess.Popen(['runas', '/user:Administrator', 'calc.exe'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
p.stdin.write(b'YourPassword\n')
p.stdin.flush()
stdout, stderr = p.communicate()
print("-----------")
print(stdout)
print("-----------")
print(stderr)
I have avoided this problem by approaching it using command prompt rather than using subprocess.
def runExecutables():
os.system(r"start C:\Users\Mastodon\Desktop\SURVEY_PROGRAM_WINDOWS_ENGLISH.exe")
Using command prompt alleviates some of the problems that subprocess would inflict. I am unclear as to what the advantages of using subprocess are.
Related
I am trying to run a youtube-dl command but when os.system(command) run, it is waiting an input on terminal(there is no input required). I press enter 2-3 time than it starts downloading.
url = sys.argv[1]
command = "youtube-dl " + url
print("downloading...")
os.system(command)
print("test")
I can't see "test" output. command works on cmd properly. waiting or subprocess command not working.
Using subprocess instead of os.system will let you set stdin=subprocess.DEVNULL so it can't read from stdin (without going to the TTY, which most programs don't). Also, passing a list and keeping the default shell=False avoids security issues where contents inside the URL could be treated by the shell as commands to run.
subprocess.run(["youtube-dl", url], stdin=subprocess.DEVNULL)
I've been trying to run some applications with arguments in windows command prompt, but within a Python script. I am encountering issues in understanding the subprocess module and how I could use it to send inputs, capture outputs and use the data in future functions or loops.
Let's take, for example, Windows Management Instrumentation Command-Line:
I would like to launch a command prompt from a Python script, start wmic, do some stuff then exit back to command prompt.
I know how to strat the cmd and even wmic:
import subprocess
cmd = subprocess.Popen(["cmd", "/K", "wmic"])
What I don't know is how to send commands to wmic. I have tried the following:
import subprocess
cmd = subprocess.Popen(["cmd", "/K", "wmic"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdoutdata, stderrdata = cmd.communicate(input="product get name")
or
cmd.stdin.write("product get name")
cmd.stdin.flush()
Doesn't work. What I would've wanted in this example, is to start Command Prompt, start WMIC, send a command (product/process get name), capture the output of WMIC and use it to do something:
for line in cmd.stdout:
if line == "some string":
do this or do that
In the same time, I would like the output to be printed in the opened command prompt.
I would appreciate any help.
I need to automate a few bash scripts which involves answering to read prompts with y/n.
I tried to pipe stdout/stderr/stdin to a python script. Writing to stdin works but reading the prompt text from stdout/stderr doesn't for some reason? (I can read everything else that bash or sub-processes output fine.)
>>> from subprocess import Popen, PIPE
>>> proc = Popen(['bash','-c','read -r -p "Update system? [y/N] " response'],stdout=PIPE,stdin=PIPE,stderr=PIPE)
>>> proc.stdout.read(10) # <-- hangs, same with stderr, any length
I was expecting I would be able to read displayed prompt "Update system? [y/N] " somehow so I can decide what answer to pass back.
This is what expect is good at:
https://likegeeks.com/expect-command/
Expect and bash
https://unix.stackexchange.com/questions/351446/bash-and-expect-in-the-same-script
I am writing a script in Python3 that makes a subprocess.call, and that call requires that the user writes a password.
I want the script to call the subprocess and afterwards automatically write the password, but so far I've had no success.
I am executing it from a Linux machine, if it's any help.
I have tried with Popen and Pipe
p = Popen("Command that when executed requires me to input a password", shell=True, stdin=PIPE)
p.stdin.write(PASSWORD.encode("UTF-8"))
This gives an error stating that the password could not be read (meaning at least it completes the process)
and also with normal subprocess.call
subprocess.call(COMMAND)
sys.stdin.write(PASSWORD)
In this case, it waits until I press ENTER and then it executes the next line.
Try:
p1 = subprocess.Popen(['echo','PASSWORD'], stdout=PIPE)
subprocess.Popen("Command that when executed requires me to input a password", stdin=p1.stdout)
p1.stdout.close()
first you echo something to pipe, which is used as input to second subprocess
Password are not expected to be read from a file when they are asked interactively, but only from the terminal.
On Unix/Linux, it is common that programs asking for a password actually read from /dev/tty instead of standard input. A simple way to confirm it is to write:
echo password | path/to/command_asking_for_password
If it blocks waiting for the password, it is likely that the password is read from /dev/tty.
What can be done?
read the docs. Some programs have special options to pass a password directly as a command line parameter, or to force the read from stdin
use a pseudo-terminal. It is slightly more complex that a simple redirection and non portable outside the Linux/Unix world, but the slave part of the pty is seen by the program as its real /dev/tty.
import pty
import os
import subprocess
...
master, slave = pty.openpty()
p = Popen("Command that when executed requires me to input a password", shell=True, stdin=slave)
os.write(master, PASSWORD.encode("UTF-8"))
...
p.wait()
os.close(master)
os.close(slave)
I've managed to get the cmd being opened by python. However, using runas administrator comes with a password check before cmd.exe is executed.
I'm using this to open cmd...
import subprocess
subprocess.call(["runas", "/user:Administrator", "cmd.exe"])
I'm looking for a way to automatically enter the password into the runas.exe prompt which opens when i run the code. Say if i were to create var = "test" and add it after import subprocess how would i make it so that this variable is passed to and seen as an input to the runas.exe?
The solution would require only python modules which are in version 3.4 or higher.
Update
I have found some code which appears to input straight into runas.exe. However, the apparent input is \x00\r\n when in the code the input is supposed to be test I am fairly certain that if i can get the input to be test then the code will be successful.
The code is as follows :
import subprocess
args = ['runas', '/user:Administrator', 'cmd.exe']
proc = subprocess.Popen(args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
proc.stdin.write(b'test\n')
proc.stdin.flush()
stdout, stderr = proc.communicate()
print (stdout)
print (stderr)
Although not an answer to your question, this can be a solution to your problem. Use psexec instead of runas. You can run it like this:
psexec -u user -p password cmd
(or run it from Python using subprocess.Popen or something else)
This piece of code actually works (tested on a Windows 2008 server). I've used it to call runas for a different user and pass his password. A new command prompt opened with new user context, without needing to enter password.
Note that you have to install pywin32 to have access to the win32 API.
The idea is:
to Popen the runas command, without any input redirection, redirecting output
read char by char until we encounter ":" (last char of the password prompt).
send key events to the console using win32 packages, with the final \r to end the password input.
(adapted from this code):
import win32console, win32con, time
import subprocess
username = "me"
domain = "my_domain"
password ="xxx"
free_console=True
try:
win32console.AllocConsole()
except win32console.error as exc:
if exc.winerror!=5:
raise
## only free console if one was created successfully
free_console=False
stdin=win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
p = subprocess.Popen(["runas",r"/user:{}\{}".format(domain,username),"cmd.exe"],stdout=subprocess.PIPE)
while True:
if p.stdout.read(1)==b":":
for c in "{}\r".format(password): # end by CR to send "RETURN"
## write some records to the input queue
x=win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
x.Char=unicode(c) # remove unicode for python 3
x.KeyDown=True
x.RepeatCount=1
x.VirtualKeyCode=0x0
x.ControlKeyState=win32con.SHIFT_PRESSED
stdin.WriteConsoleInput([x])
p.wait()
break