PYTHON: How To Print SSH Key Using Python - python-2.7

I've been trying to make a script that can print the Ubuntu SSH key located in ~/.ssh/authorised_keys/
Basically I want the script to print out exactly what cat ~/.ssh/authorised_keys/ would output.
I have tried using subprocess.check_output but it always returns an error.
Thanks

What about this ?
import os
os.system('cat ~/.ssh/authorised_keys')

If you want to capture the output to a variable, use subprocess. If not, you can use os.system as user803422 has mentioned
import os, subprocess
path = '~/.ssh/authorized_keys'
cmd = 'cat ' + os.path.expanduser(path)
output = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
response = output.communicate()
print (response)

You can read the file directly in Python, there is not really a need to use subprocess:
import os
print(open(os.path.expanduser('~/.ssh/authorized_keys')).read())

Related

Not able to redirect output of the command to a file

My problem is after executing below code I am able to see outputs of each command in shell. How can I get that shell output to the file
I have tried with the below but it does not work
python pr.py >> pr.txt
import os
f=open("pr1.txt","r")
df=0
for i in f:
df=df+1
if df==4:
break
print i
os.system("udstask expireimage -image" + i)
After executing "os.system("udstask expireimage -image" + i)" every time this will display status of the command to the file
You could try something like :
import os
f=open("pr1.txt","r")
df=0
for i in f:
df=df+1
if df==4:
break
print i
os.system("udstask expireimage -image" + i + " > pr.txt")
It would redirect the output of the command to pr.txt.
You should use subprocess instead of os.system which has more efficient stream handling and gives you more control while calling a shell command:
import os
import subprocess
f=open("pr1.txt","r")
df=0
for i in f:
df=df+1
if df==4:
break
print i
task = subprocess.Popen(["udstask expireimage -image" + i],stdout=subprocess.PIPE,shell=True)
task_op = task.communicate()
task.wait()
Now you have your output stored in task_op which you can write onto a file or do whatever you wish to. It is in tuple form and you may need to write only required part.

How to use regular expressions to pull something from a terminal output?

I'm attempting to use the re module to look through some terminal output. When I ping a server through terminal using ping -n 1 host (I'm using Windows), it gives me much more information than I want. I want just the amount of time that it takes to get a reply from the server, which in this case is always denoted by an integer and then the letters 'ms'. The error I get explains that the output from the terminal is not a string, so I cannot use regular expressions on it.
from os import system as system_call
import re
def ping(host):
return system_call("ping -n 1 " + host) == 0
host = input("Select a host to ping: ")
regex = re.compile(r"\w\wms")
final_ping = regex.search(ping(host))
print(final_ping)
system returns 0, not anything too useful. However, if we were to do subprocess, we can get teh output, and store it to a variable, out, then we can regex search that.
import subprocess
import re
def ping(host):
ping = subprocess.Popen(["ping", "-n", "1", host], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, error = ping.communicate()
return str(out)
host = input("Select a host to ping: ")
final_ping = re.findall("\d+ms",ping(host))[0]
print(final_ping)
Output:
22ms
There are two problems with your code:
Your ping function doesn't return the terminal output. It only returns a bool that reports if the ping succeeded. The ping output is directly forwarded to the terminal that runs the Python script.
Python 3 differentiates between strings (for text, consisting of Unicode codepoints) and bytes (for any data, consisting of bytes). As Python cannot know that ping only outputs ASCII text, you will get a bytes object if you don't specify which text encoding is in use.
It would be the best to use the subprocess module instead of os.system. This is also suggested by the Python documentation.
One possible way is to use subprocess.check_output with the encoding parameter to get a string instead of bytes:
from subprocess import check_output
import sys
def ping(host):
return check_output(
"ping -n 1 " + host,
shell=True,
encoding=sys.getdefaultencoding()
)
...
EDIT: The encoding parameter is only supported since Python 3.6. If you are using an older version, try this:
from subprocess import check_output
import sys
def ping(host):
return check_output(
"ping -n 1 " + host,
shell=True
).decode()
...

Hadoop commands from python script?

I have multiple hadoop commands to be run and these are going to be invoked from a python script. Currently, I tried the following way.
import os
import xml.etree.ElementTree as etree
import subprocess
filename = "sample.xml"
__currentlocation__ = os.getcwd()
__fullpath__ = os.path.join(__currentlocation__,filename)
tree = etree.parse(__fullpath__)
root = tree.getroot()
hivetable = root.find("hivetable").text
dburl = root.find("dburl").text
username = root.find("username").text
password = root.find("password").text
tablename = root.find("tablename").text
mappers = root.find("mappers").text
targetdir = root.find("targetdir").text
print hivetable
print dburl
print username
print password
print tablename
print mappers
print targetdir
p = subprocess.call(['hadoop','fs','-rmr',targetdir],stdout = subprocess.PIPE, stderr = subprocess.PIPE)
But, the code is not working.It is neither throwing an error not deleting the directory.
I suggest you slightly change your approach, or this is how I'm doing it. I make use of python library import commands which then depends how you will use it (https://docs.python.org/2/library/commands.html).
Here is a lil demo:
import commands as com
print com.getoutput('hadoop fs -ls /')
This gives you output like (depending on what you have in the HDFS dir )
/usr/local/Cellar/hadoop/2.7.3/libexec/etc/hadoop/hadoop-env.sh: line 25: /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home: Is a directory
Found 2 items
drwxr-xr-x - someone supergroup 0 2017-03-29 13:48 /hdfs_dir_1
drwxr-xr-x - someone supergroup 0 2017-03-24 13:42 /hdfs_dir_2
Note: the lib commands doesn't work with python 3 (to my knowledge), I'm using python 2.7.
Note: Be aware of the limitation of commands
If you will use subprocess which is the equivalent to commands for python 3 then you might consider to find a proper way to deal with your 'pipelines'. I find this discussion useful in that sense: (subprocess popen to run commands (HDFS/hadoop))
I hope this suggestion helps you!
Best

how to assign or copy values from command line arguments to the standard input???i have written program but i am unable to do it

from subprocess import call
import sys
import os
import subprocess
if(call("hg clone --insecure https://mixmaster.netwitness.local/" + "sys.argv[1]", shell=True)):
sys.stdin = sys.argv[2]
sys.stdin = sys.argv[3]
else :
print("error")
Is there a reason why the argument is in quotes? Also use % to replace tokens in your string. Change it to this:
if(call("hg clone --insecure https://mixmaster.netwitness.local/%s" % sys.argv[1], shell=True)):
EDIT
If you want to pass all the arguments separated by spaces, use this
if(call("hg clone --insecure https://mixmaster.netwitness.local/%s" % (" ".join(sys.argv[1:])), shell=True)):
subprocess.call is more easily called with a list of parameters. That way you don't have to worry about spaces in the arguments that you want to give to hg. As you indicate in your comments on #Rajesh answer, that you want 3 arguments passed to hg, the following should work:
from subprocess import call
import sys
import os
import subprocess
cmd = ["hg", "clone", "--insecure", "https://mixmaster.netwitness.local/", sys.argv[1], sys.argv[2], sys.argv[3]]
if not (call(cmd, shell=True)):
print("error")
If you really want to provide sys.argv[2] and sys.argv[3] as the input to hg prompts. You should not use call as it can block the hg process, use Popen.

How do I retrieve program output in Python?

I'm not a Perl user, but from this question deduced that it's exceedingly easy to retrieve the standard output of a program executed through a Perl script using something akin to:
$version = `java -version`;
How would I go about getting the same end result in Python? Does the above line retrieve standard error (equivalent to C++ std::cerr) and standard log (std::clog) output as well? If not, how can I retrieve those output streams as well?
Thanks,
Geoff
For python 2.5: sadly, no. You need to use subprocess:
import subprocess
proc = subprocess.Popen(['java', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
Docs are at http://docs.python.org/library/subprocess.html
In Python 2.7+
from subprocess import check_output as qx
output = qx(['java', '-version'])
The answer to Capturing system command output as a string question has implementation for Python < 2.7.
As others have mentioned you want to use the Python subprocess module for this.
If you really want something that's more succinct you can create a function like:
#!/usr/bin/env python
import subprocess, shlex
def captcmd(cmd):
proc = subprocess.Popen(shlex.split(cmd), \
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
out, err = proc.communicate()
ret = proc.returncode
return (ret, out, err)
... then you can call that as:
ok, o, e = captcmd('ls -al /foo /bar ...')
print o
if not ok:
print >> sys.stderr, "There was an error (%d):\n" % ok
print >> sys.stderr, e
... or whatever.
Note: I'm using shlex.split() as a vastly safer alternative to shell=True
Naturally you could write this to suit your own tastes. Of course for every call you have to either provide three names into which it can unpack the result tuple or you'd have to pull the desired output from the result using normal indexing (captcmd(...)[1] for the output, for example). Naturally you could write a variation of this function to combine stdout and stderr and to discard the result code. Those "features" would make it more like the Perl backtick expressions. (Do that and take out the shlex.split() call and you have something that's as crude and unsafe as what Perl does, in fact).