Re: [Tutor] os.popen - using commands and input %
On Mon, Nov 16, 2015 at 4:17 AM, Vusa Moyo wrote: > Hi Guys, > > My code is as follows > > # this list contains system process ID's > pidst=[1232, 4543, 12009] > > pmap_str=[] > command="pmap -d %s | grep private |awk '{print $1}' | awk -FK '{print $1}'" > > for i in range(len(pids)): > pmap_str.append(os.popen("(command) % pidlist_int[i])")) Hi Vusa, If you can, please try to avoid using os.popen() or subprocess.call() with formatted strings: that's a common security risk that's known as a "code injection" vulnerability. https://en.wikipedia.org/wiki/Code_injection More generally, your program is over-using strings to do things that they aren't meant to do. One of the habits of the beginner is to try to do everything in terms of strings, since strings are flexible. But this approach often ignores features of the language that might be more appropriate. I brought up that constructing the command pipeline string is one thing to try to avoid with string formatting. But it tries to use strings in another way that is somewhat unnatural: it is trying to encode the idea of re-using the command pipeline so you can feed it different pids "(command) % pidlist_int[i]) This idea of reuse is admirable, but the execution with string formatting can be improved. An alternative approach can use the language's natural construct for reusability: the function. We can write a function to construct a command that is parameterized on the given pid. The rest of this message will sketch out what this looks like. --- What you're doing here: pmap -d | grep private |awk '{print $1}' | awk -FK '{print $1}' can be translated to a sequence of operations that does not use any string formatting to construct command lines. See: https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline. If we apply this to your command, we should expect to see something like this (untested) # def get_pmap(pid): p1 = Popen(['pmap', '-d', str(pid)], stdout=PIPE) p2 = Popen(['grep', 'private'], stdin=p1.stdout, stdout=PIPE) p3 = Popen(['awk', '{print $1}'], stdin=p2.stdout, stdout=PIPE) p4 = Popen(['awk', 'FK', '{print $1}'], stdin=p3.stdout, stdout=PIPE) p1.stdout.close() return p4.communicate()[0] # Here, we package up this collection of statements into a function that takes in a pid and returns the result. Note that we don't have to do any string concatenation or string formatting. After which, we can apply this function across your list directly. pmap_str = [get_pmap(pid) for pid in pidst] ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] os.popen - using commands and input %
On 16/11/15 14:05, Vusa Moyo wrote: SOLVED> the code I used was. for i in range(len(pids)): final.append(subprocess.Popen(["sudo pmap -d %s | grep private |awk '{print $1}' | awk -FK '{print $1}'" % pids[i]], shell=True, Glad you solved it and using subprocess is fine for the pmap stuff. But the grep and awk stuff are usually a lot faster and almost as easy using Python. eg. for line in pmap_output if private in line: print line.split()[0]# {print $1} Or, to create a list instead of printing col1 = [line.split()[0] for line in pmap_output if private in line] I can't remember what -FK does (F is field sep but K?) But I'm fairly sure it will be easy to replicate in Python. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] os.popen - using commands and input %
SOLVED> the code I used was. for i in range(len(pids)): final.append(subprocess.Popen(["sudo pmap -d %s | grep private |awk '{print $1}' | awk -FK '{print $1}'" % pids[i]], shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[0]) Allowed me to append the subprocess output to my list. Thanks for the help everyone :-) On Mon, Nov 16, 2015 at 3:07 PM, Vusa Moyo wrote: > The following code seems to be pointing me to the right direction, BUT, my > list has 0's instead of the output generated. > > >>> for i in range(len(pids)): > ... final.append(subprocess.call(["sudo pmap -d %s | grep private |awk > '{print $1}' | awk -FK '{print $1}'" % pids[i]], shell=True)) > ... > 60772 > 106112 > 3168 > 13108 > 14876 > 8028 > 3328 > 8016 > 139424 > 6037524 > 5570492 > 4128 > 144364 > 154980 > 154980 > >>> pmap_str > [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] > > I;m assuming the zero's are exit codes, which then populate the list, > which is not what I'm after. . > > On Mon, Nov 16, 2015 at 2:17 PM, Vusa Moyo wrote: > >> Hi Guys, >> >> OS = SuSE Enterprise Linux >> Python V2.7 >> >> My code is as follows >> >> # this list contains system process ID's >> pidst=[1232, 4543, 12009] >> >> pmap_str=[] >> command="pmap -d %s | grep private |awk '{print $1}' | awk -FK '{print >> $1}'" >> >> for i in range(len(pids)): >> pmap_str.append(os.popen("(command) % pidlist_int[i])")) # <-- >> this is where I need help, please >> >> As I'm sure you can see, I'm trying to output the os.popen output to a >> new list. >> >> On the shell console I can run the pmap command as follows >> >> pmap -d | grep private |awk '{print $1}' | awk -FK '{print $1}' >> >> Output will be a single number such as 485921. >> >> My error is on the line of code shown above. Please assist. >> >> Kind Regards >> > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] os.popen - using commands and input %
The following code seems to be pointing me to the right direction, BUT, my list has 0's instead of the output generated. >>> for i in range(len(pids)): ... final.append(subprocess.call(["sudo pmap -d %s | grep private |awk '{print $1}' | awk -FK '{print $1}'" % pids[i]], shell=True)) ... 60772 106112 3168 13108 14876 8028 3328 8016 139424 6037524 5570492 4128 144364 154980 154980 >>> pmap_str [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] I;m assuming the zero's are exit codes, which then populate the list, which is not what I'm after. . On Mon, Nov 16, 2015 at 2:17 PM, Vusa Moyo wrote: > Hi Guys, > > OS = SuSE Enterprise Linux > Python V2.7 > > My code is as follows > > # this list contains system process ID's > pidst=[1232, 4543, 12009] > > pmap_str=[] > command="pmap -d %s | grep private |awk '{print $1}' | awk -FK '{print > $1}'" > > for i in range(len(pids)): > pmap_str.append(os.popen("(command) % pidlist_int[i])")) # <-- > this is where I need help, please > > As I'm sure you can see, I'm trying to output the os.popen output to a new > list. > > On the shell console I can run the pmap command as follows > > pmap -d | grep private |awk '{print $1}' | awk -FK '{print $1}' > > Output will be a single number such as 485921. > > My error is on the line of code shown above. Please assist. > > Kind Regards > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor