PDA

View Full Version : Python - execute command without blocking



tom66
December 25th, 2008, 09:28 PM
I'm trying to get the information from this:



command_lines = os.system('sudo apt-get autoremove')


But the command blocks when it asks if I want to continue. How do I get my information in a string and then get the process to stop? Or is there another way of accessing the information I want? (the space used by packages which could be automatically removed).

Thanks

Jacks0n
December 25th, 2008, 10:32 PM
What do you mean it blocks? You mean it waits for the user's input? Technically you can interact with the shell using subprocess.Popen, but in your case I'd change the command to...


command_lines = os.system('gksudo apt-get -y autoremove')

This means it'll use a graphical program to get the user's password and won't hang when asking for it at the terminal. Plus the y flag means automatically say yes to whatever apt-get asks, so it'll no longer ask to confirm.

- Jackson

tom66
December 25th, 2008, 10:57 PM
I mean it waits for user input. I'm aware of the -y flag, it doesn't do what I need - I need to get the information, such as the size of the autoremove data, without executing the command fully. I can parse a load of text if necessary.

Ahadiel
December 26th, 2008, 08:58 AM
AFAIK, os.system returns the PID of the command being run. You want to use os.popen

command_lines = os.popen("sudo apt-get -y autoremove").readlines()
That will make command_lines a list containing each line of the command's output.

tom66
December 26th, 2008, 12:13 PM
Will I be able to get the contents of the command and read it if it is waiting for user input? I'm aware of the -y flag and it doesn't do what I want in particular. What I need to do is get the line that says "After this operation, 354MB disk space will be freed", then terminate the command. Is it possible to read the lines as they come in one-by-one and then terminate on demand? Or, is there a better way of going after the data which I need - the amount of space used by autoremove data. Like using a dpkg library for python.

Thanks.

Ahadiel
December 26th, 2008, 04:59 PM
command_lines = os.popen("echo 'y' | gksudo apt-get autoremove").readlines()

nvteighen
December 26th, 2008, 05:40 PM
I guess there's some way to do this using a call to the APT library.

imdano
December 26th, 2008, 08:45 PM
I would use subprocess.Popen(), which is designed to replace os.popen().

Will I be able to get the contents of the command and read it if it is waiting for user input? I'm aware of the -y flag and it doesn't do what I want in particular. What I need to do is get the line that says "After this operation, 354MB disk space will be freed", then terminate the command. Is it possible to read the lines as they come in one-by-one and then terminate on demand? Or, is there a better way of going after the data which I need - the amount of space used by autoremove data. Like using a dpkg library for python.

Thanks.Yes. Once you get the Popen object back you can created a loop that call readline() on the handle to stdout, which will let you read the output of the command line by line. You can then do whatever you want based on what you read in, including writing to the process' stdin.

edit: It is probably a good idea to follow nvteighen's suggestion and see if you can get the information through calls to the libapt. Install the python-apt package to get python bindings for it.

Flimm
December 27th, 2008, 01:13 PM
I think you would find pexpect (http://www.noah.org/wiki/Pexpect) useful, it allows you to control other processes as if it were a human typing in a terminal. The site has some easy to understand examples.