I've just started to write a monitoring tool in Python 3, and I'm wondering if I can get a 'clear' number output through ssh. I've written this script:
import os
import paramiko
command = 'w|grep \"load average\"|grep -v grep|awk {\'print ($10+$11+$12)/3*100\'};'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy( paramiko.AutoAddPolicy())
ssh.connect('10.123.222.233', username='xxx', password='xxx')
stdin, stdout, stderr = ssh.exec_command(command)
print (stdout.readlines())
ssh.close()
It works fine, except the output is:
['22.3333\n']
How can I get rid of the [' and \n'] and just get the clear number value?
How can I get the result as I see it in PuTTy?
.readlines() returns a list of separate lines. In your case there is just one line, you can just extract it by indexing the list, then strip of the whitespace at the end:
firstline = stdout.readlines()[0].rstrip()
This is still a string, however. If you expected numbers, you'd have to convert the string to a float(). Since your command line will only ever return one line, you may as well just use .read() and convert that straight up (no need to strip, as float() is tolerant of trailing and leading whitespace):
result = float(stdout.read())
Instead of print(stdout.readlines()) you should iterate over each element in the list that is returned by stdout.readlines() and strip it, possibly converting it to float as well (depends what you are planning to do with this data later).
You can use list comprehension for this:
print([float(line.strip()) for line in stdout.readlines()])
Note that strip will remove whitespaces and new-line chars from both the start and end of the string. If you only want to remove the trailing whitespace/new-line char then you can use rstrip, but note that the conversion to float may then fail.
Related
I am making a server that asks for you IP address and I want to make an option that says (leave blank for __your ip__) but I'm having trouble with it. I tried doing this
import subprocess
output = subprocess.check_output("ipconfig getifaddr en0", shell=True)
but it returns
b'***.***.***.***\n' is there a way to remove the '', b and \n or another way to get an IP that doesn't return 127.0.0.1?
What you're seeing is the bytestring output and the following newline.
You'll want
output = subprocess.check_output("ipconfig getifaddr en0", shell=True).decode().strip()
to first decode the bytes as UTF-8, then strip whitespace from the start and the end.
I am using Python sub process to execute command as shown below:
process = subprocess.Popen(['debug', 'file.tgz'],
stdout=subprocess.PIPE,stderr=subprocess.PIPE)
while True:
output = process.stdout.readline()
print(str(output.strip()).encode())
return_code = process.poll()
if return_code is not None:
break
What i am getting out put is shown below:
b"b'Registers:'"
And this is what i am expecting.
Registers:
I am using encode but still seeing same out put. If i run the same process on command line i am getting the same desired out put.
How can i remove these special characters?
Skip the str(); that'll get rid of the inner b'...'
You want to .decode rather than .encode, because you want to turn a byte-stream (which came from the subprocess) into a string (for printing). You'll need to know which encoding it's using, and (if applicable) what to do with malformed data.
(optional) Strip the whitespace after decoding, not before, to also strip non-ASCII whitespace characters (if any).
print(output.decode('utf8', errors='strict').strip())
In Python 3.7, I am trying to write a JSON array to stdout and I would like to remove the final comma in the array
sys.stdout.write("[")
[sys.stdout.write(json.dumps(x, separators=(',', ': ')) + ",") for x in list]
sys.stdout.write("\b]") # I want to remove the final ',' from above.
I know sys.stdout is buffered, so what I'd like to do is remove the last character in that buffer before the flush. The only problem is I don't know how to properly access that buffer as well as ensure the final byte is not written.
I messed with the \b character however that does nothing, all that happens is the \b character becomes part of the output.
As a background, the stdout is going into an Apache NiFi flow (not to a console window). I'd much rather use stdout and not a secondary in-memory buffer as that feels like such a waste of memory. It'd be great if I could remove the last byte of the stdout buffer before flushing.
EDIT:
Some folks in the comments are suggesting my use of list comprehensions isn't the way to go here and instead run json.dumps on the list. If anyone has an example of how to use this and ensure the last element doesn't have a trailing comma, please show it!
The simplest solution is just to dump the whole list at once:
sys.stdout.write(json.dumps(list, separators=(',', ': '))
But if you really need to write each element separately you could make the comma conditional:
last_index = len(list) - 1
sys.stdout.write("[")
for i, x in enumerate(list):
sys.stdout.write(json.dumps(x, separators=(',', ': '))
if i < last_index:
sys.stdout.write(',')
sys.stdout.write("]")
I am trying to format the string below with variables for readability, I would like to break it up so it easier read, right now it takes up 199 characters in the script line, every attempt I make seems to break it up so when printed it has large gaps, can anyone shed some light? I tried wrapping it in """ triple quotes and \ at the end but it still has spaces when printed or logged.
copy_sql = "COPY {0} FROM 's3://{1}/{2}' CREDENTIALS 'aws_access_key_id={3};aws_secret_access_key={4}' {5}; ".format(table_name,bucket,key,aws_access_key_id,aws_secret_access_key,options)
Desired result would be something to this affect:
copy_sql = "COPY {0} FROM 's3://{1}/{2}' \
CREDENTIALS 'aws_access_key_id={3};aws_secret_access_key={4}' {5}; \
".format(table_name,bucket,key, \
aws_access_key_id,aws_secret_access_key,options)
However when I print it I get large spaces between .gz and credentials:
COPY analytics.table FROM 's3://redshift-fake/storage/2017-11-02/part-00000.gz' CREDENTIALS 'aws_access_key_id=SECRET;aws_secret_access_key=SECRET' DELIMITER '\t' dateformat 'auto' fillrecord removequotes gzip;
I am thinking this would still work but I would like to clean it up for logging readability.
You can use string literal concatenation:
Multiple adjacent string literals (delimited by whitespace), possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. Thus, "hello" 'world' is equivalent to "helloworld".
In your case, something like this:
copy_sql = ("COPY {0} FROM 's3://{1}/{2}' "
"CREDENTIALS 'aws_access_key_id={3};aws_secret_access_key={4}' {5};"
).format(table_name,bucket,key,
aws_access_key_id,aws_secret_access_key,options)
Note the extra parentheses to make it parse correctly. As long as a line ending is inside at least one pair of parenthes, Python will always treat it as a line continuation, without the need for backslashes.
How do i get rid of the extra character at the end of a line when i flush output?
Output:
{Fifth Level} Last Key Ran: 7 Output: -7 =
That '=' is what i want to get rid of.
code:
for number in str(fourth_level):
x=int(number)
x=x^(priv_key-pub_key)
print "\r{Fifth Level} Last Key Ran:",str(number),"Output:",x,
sys.stdout.flush()
time.sleep(sleep_time)
fifth_level.append(x)
Also is there any way to get multiple lines outputting data at the same time without going down one line or changing format? Using flush it gets rid of the second line output.
As a side note, check the ,x, part of the print statement. That 'x' is fishy.
For string manipulations, try writing everything into a temporary string first. You can then edit that string. This will give you more control over editing it.
Also, rstrip might do the trick if the characters being displayed are consistent.
Reference:
* http://docs.python.org/library/string.html
"string.rstrip(s[, chars]) Return a copy of the string with trailing characters removed."