views:

101

answers:

3

I'm tired of going through all the steps it takes (for me) to change the DocumentRoot in Apache. I'm trying to facilitate the process with the following Python script...

#!/usr/bin/python

import sys, re

if len(sys.argv) == 2:
 f = open('/tmp/apachecdr', 'w')
 f.write(open('/etc/apache2/httpd.conf').read())

 f = open('/tmp/apachecdr', 'r')
 r = re.sub('DocumentRoot "(.*?)"', 
  'DocumentRoot "' + sys.argv[1] + '"', 
  f.read())
 f = open('/etc/apache2/httpd.conf', 'w')
 f.write(r)
else:
 print "Please supply the new DocumentRoot path."

I've saved this as /usr/bin/apachecdr so that I could simply open a shell and "sudo apachecdr /new/documentroot/path" and then restart with apachectl. My question is how would you write this?

It's my first time posting on Stack Overflow (and I'm new to Python) so please let me know if this is not specific enough of a question.

A: 

You're doing a lot of file work for not much benefit. Why do you write /tmp/apachecdr and then immediately read it again? If you are copying httpd.conf to the tmp directory as a backup, the shutil module provides functions to copy files:

#!/usr/bin/python

import shutil, sys, re

HTTPD_CONF = '/etc/apache2/httpd.conf'
BACKUP = '/tmp/apachecdr'
if len(sys.argv) == 2:
 shutil.copyfile(BACKUP, HTTPD_CONF)
 conf = open(HTTPD_CONF).read()

 new_conf = re.sub('DocumentRoot "(.*?)"', 
  'DocumentRoot "' + sys.argv[1] + '"', 
  conf)
 open(HTTPD_CONF, 'w').write(new_conf)
else:
 print "Please supply the new DocumentRoot path."
Ned Batchelder
A: 

In general Python programmers prefer explicit over implicit (see http://www.python.org/dev/peps/pep-0020/). With that in mind you may want to rewrite this line

f.write(open('/etc/apache2/httpd.conf').read())

To:

infile = open('/etc/apache2/httpd.conf').read()
f.write(infile)
infile.close()

Another suggestion would be to add some error checking. For example checking that the file /etc/apache2/httpd.conf exists.

Normally one would use a try/except around the open line, but if you want to use the combined read and the write command you could use a os.stat for checking.

Example

import os
try:
  os.stat('/etc/apache2/httpd.conf) 
except OSError:
  print "/etc/apache2/httpd.conf does not exist"
  return #will exit the program
Felix
`infile` in your code is a string (the result of `.read()`), so you'd better not call `.close()` on it...;-)
Alex Martelli
A: 

Thank you both for your answers. Ned, I was hoping you'd say something like that. The reason I was doing it like that is simply because I didn't know better. Thanks for providing your code, it was exactly what I was looking for.

Btw, the error is happening because "BACKUP" and "HTTPD_CONF" are reversed on line 8. In other words, switch "shutil.copyfile(BACKUP, HTTPD_CONF)" to "shutil.copyfile(HTTPD_CONF, BACKUP)" on line 8 of Ned's script.

Thanks again guys! This was a great first experience posting on this site.