I'm having a lot of trouble passing a string to the openssl commandline tool via python's subprocess like this:
process = subprocess.Popen(
["openssl", "rsa", "-in", pathFile, "-out", "id_rsa.out"],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
shell=False
)
try:
process.communicate("some passphrase\n", timeout=2)
except:
process.kill() #openssl stays alive otherwise.
The code above times out (with and without the std redirection in the Popen). I can use openssl normally through the terminal just fine, but I really need to be able to run this as part of my python script.
Any help would be appreciated.
The section PASS PHRASE ARGUMENTS on the openssl man page explains how the passphrase input mechanism works. To make your example work, you should tell openssl to take the passphrase from stdin. Using your example as a starting point, the following works for me:
process = subprocess.Popen(
["openssl", "rsa", "-in", pathFile, "-out", "id_rsa.out", "-passin", "stdin"],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
shell=False
)
process.communicate("passphrase\n")
Related
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)
I run this curl command in the unix shell and it works (see below). I was able to redirect the returned data to a file but now I want to process the data in my code instead of wasting a bunch of space in a file.
curl -k -o outputfile.txt 'obfuscatedandVeryLongAddress'
#curl command above, python representation below
addr = "obfuscatedandVeryLongAddress"
theFile = subprocess.Popen(["curl", "-k", addr], stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
theFile.stdout is empty after this. The data returned in the curl command should be something like 4,000 lines (verified when running the command in the shell). Is the size breaking theFile.stdout? Am I doing something else wrong? I tried using:
out, err = theFile.communicate()
and then printing the out variable but still nothing
edit: formatting and clarification
You need to remove shell=True.
theFile = subprocess.Popen(["curl", "-k", addr], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
Should work.
If you do shell=True, you should pass a string. Otherwise, what you're actually doing is passing those arguments -k, and addr as arguments to the shell. So if your shell is sh, what you're doing is sh 'curl' -k addr.
Eugene's is a direct answer to your question, but I thought I'd add one on using the requests library, since it will require less code and be easier to read for anyone that needs to look at your code (and has the benefit of being cross-platform).
import requests
response = requests.get('longaddress', verify=False)
print response.text
If the response is json, you can automatically convert it to a python object
print response.json()
You can put the curl command in a string like:
theFile = subprocess.Popen('curl -k {}'.format(addr), stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
Or you can remove the shell argument:
theFile = subprocess.Popen(["curl", "-k", addr], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
Or you could use the pycurl module to use libcurl library directly and skip the whole additional process.
When I use subprocess I can normally capture the stdout and display it however I like. E.g,
import subprocess
proc = subprocess.Popen(['./foo.py'], stdin=subprocess.Pipe, stdout=subprocess.Pipe)
# the standard out is not displayed unless I do something with the stdout var
stdout, stderr = proc.communicate()
However, if I use subprocess to call the Linux passwd utility, the standard out is displayed as soon as proc.communicate() is called:
import subprocess
proc = subprocess.Popen(['passwd', 'foo'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# standard out is displayed immediately
stdout, stderr = proc.communicate('password\npassword\n')
BAD PASSWORD: it is based on a dictionary word
Retype new password:
How come this happens only with passwd? For example, it doesn't happen with ls. Is there anything I can do to prevent the standard out from being printed when calling passwd from subprocess?
Note that I want to actually capture the standard out and do something with it later, so I would not want to set stdout to a devnull pipe.
It only happens with passwd because passwd directly communicates with the TTY, not via stdin or stdout. This is a security measure, and accepted best practice for prompting for a password directly from a user.
If you really must bypass this security measure, consider using the unbuffer utility (shipped with expect) to create a fake TTY:
p = subprocess.Popen(['unbuffer', 'passwd', 'foo'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate('password\npassword\n')
This is a follow-up from Invoke pstools in Python script
When I open a command prompt and execute
D:\pstools\psloggedon.exe -l -x \\10.10.10.10
I get
DOMAIN\user
But when I execute the script
import sys, subprocess, socket, string
import wmi, win32api, win32con
pst = subprocess.Popen(
["D:\pstools\psloggedon.exe", "-l", "-x", "\\10.10.10.10"],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
out, error = pst.communicate()
print out, "is output"
I get
Error opening HKEY_USERS for \10.10.10.10
is output
How do I get the subprocess to read the IP address as \10.10.10.10 instead of \10.10.10.10
By the way, I tried to add third backslash
pst = subprocess.Popen(
["D:\pstools\psloggedon.exe", "-l", "-x", "\\\10.10.10.10"],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
And the output is
Error opening HKEY_USERS for .0.139.40
is output
As suggested by lejlot's comment you have to use "\\" because "\" is an escape character in python.
I am trying to use subprocess module with Popen to fetch log from a specified URL, However, I am not able to fetch the log and the program returns me a blank.
I have been using the below mentioned code:
import subprocess
url = r'C:\project\dummy\pro'
mycmd = ['svn', 'log', url]
log = subprocess.Popen(mycmd, shell=True,
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
result = log.wait()
out1, err = log.communicate()
print out1
I need the output string to use as next part of the program. Any help would be appreciated.
Try without shell=True:
log = subprocess.Popen(mycmd,
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE)