Click to See Complete Forum and Search --> : Python module os, execl() how to make it work?
lugoteehalt
08-23-2007, 01:54 PM
Python has a module 'os' that allows the computer's operating system to be used. Cannot get a program, say ls, to work properly. Someone tell me how?
From memory, doing something like:import os
args=['write', 'this', 'out']
os.execlp("echo", *args)
yeilds:this outThis is the closest I've got to getting it to work.
The instructions say the correct form is: execlp("echo", *args)
Also how is something like 'ls -l' done? Thanks any help.
saikee
08-23-2007, 05:34 PM
Well the following is my first python program ever I wrote for this thread (http://www.justlinux.com/forum/showthread.php?t=150101). It makes several calls to execute a couple of Bash commands. I have highlighted them in red.
saikee@saikee-desktop:~$ cat justlinux1.py
import os
os.system('find /abit/2007-7/Sam\ backup/Home_backup/WattArch -name *.jpg > alljpg')
os.system('find /abit/2007-7/Sam\ backup/Home_backup/WattArch -name *.JPG >> alljpg')
f=file('alljpg', 'r')
out=file('next','w')
i=0
for line in f:
i=i+1
y='"'+line.rstrip()+'"'
if i==1 :
y="ls -l "+y+" >3rd\n"
else:
y="ls -l "+y+" >>3rd\n"
print y
out.write(y)
print "total no. of *.jpg = ",i
f.close()
out.close()
os.system('/bin/bash next')
f=open('3rd', 'r')
i=0
sum=0
for line in f:
i=i+1
lst=line.split()
y=lst[4]
print i,int(y),sum
sum=sum+int(y)
print "total no. of files = ",i,"total storage (Mb) = ",sum/1000000.
f.close()
saikee@saikee-desktop:~$
Not a programmer myself but the above may gives you some idea.
bwkaz
08-23-2007, 06:51 PM
import os
args=['write', 'this', 'out']
os.execlp("echo", *args)
yeilds:this out Yep. The reason is that 'write' is going to turn into argv[0], 'this' is going to turn into argv[1], and 'out' is going to turn into argv[2].
If you know anything about C, you'll immediately see the problem: argv[0] is supposed to be the name that the user used to invoke the program, not the program's first argument. The first argument is supposed to be in argv[1].
So, to fix it, you can probably change the args array to this:
args=['echo', 'write', 'this', 'out'] and get it to work. You'll have to do the same thing with ls: make the first element of args be 'ls', and add '-l' (or other options) as subsequent elements. :)
Oh, and I'd recommend against using os.system myself. It always invokes a shell with the argument string you pass it, so if there's any problem with quotes or spaces or anything like that (or $PATH), it'll bite you. It's simpler to send an explicit array of arguments, so you know exactly what each argument is. For instance, if you're in a directory that has 2 subdirectories named "dir 1" and "dir 2" (with the space), then running os.system('ls -l dir 1') won't work. You'll have to manually quote it, like so: os.system('ls -l "dir 1"')
If you use a separate args array, then you can do: args=['ls', '-l', 'dir 1'], and that will work. No quoting required.
(This is especially helpful if the user hands you a filename that may or may not have spaces in it, and you need to process the file. If you run it through a shell, then it may get broken into multiple words, whereas if you pass it to the target command directly, it won't get broken up. OTOH, if the user is expecting to have to quote filenames, then you probably should use a shell. Also, if the process runs as root, be VERY careful with running shells. :))
lugoteehalt
08-24-2007, 12:39 PM
Huge thanks - couldn't be clearer.
Have to say it is somewhat less than obvious from a perusal of help(os) or whatever. One is supposed to believe that people are merely illiterate but I prefer something more paranoid: How about guilds looking after their turf (noone has to do this consiously, just think with the inculcated culture of the guild.) Power uses the guilds and so encourages them to do it.
ghostdog74
08-26-2007, 10:26 PM
unless absolutely necessary, my advice, is to try to write "portable" code. for your example, the ls command is specific to the shell and is not found elsewhere, eg windows. If you are going to port this code over to windows you will have a problem of changing your code. Python comes with facilities to list directories. yes, its all in the os module.
import os
for eachfile in os.listdir("yourdir"):
print eachfile