Using sudo to write to a file as root from a script

Adam Mercer ramercer at gmail.com
Fri Aug 9 09:21:22 EDT 2013


On Thu, Aug 8, 2013 at 11:47 PM, David <bouncingcats at gmail.com> wrote:

> At a quick glance, I have a couple of suggestions.
>
>>   command = ['echo', '-n', channel, '|', 'sudo', 'tee', config_file]
>
> sudo doesn't work like this. It doesn't read from standard input. You
> need to supply the command as an argument to sudo. Get the sudo syntax
> correct by learning to use it in a shell (eg terminal running bash )
> before trying to use it from python code.

The above does works in the terminal:

[ram at cizin ~]$ ls -l /opt/ldg/etc/
total 20
-rw-rw-r-- 1 ram admin 5246 Jun 14 15:15 globus-user-env.csh
-rw-rw-r-- 1 ram admin 3388 Jun 14 15:15 globus-user-env.sh
-rw-rw-r-- 1 ram admin   91 Jun 24 11:33 ldg.conf
-rw-r--r-- 1 ram admin    5 Jun 14 15:24 os.conf
$ echo -n stable | sudo tee /opt/ldg/etc/channel.conf > /dev/null
Password:
$ ls -l /opt/ldg/etc/
total 24
-rw-r--r-- 1 root admin    6 Aug  9 07:59 channel.conf
-rw-rw-r-- 1 ram  admin 5246 Jun 14 15:15 globus-user-env.csh
-rw-rw-r-- 1 ram  admin 3388 Jun 14 15:15 globus-user-env.sh
-rw-rw-r-- 1 ram  admin   91 Jun 24 11:33 ldg.conf
-rw-r--r-- 1 ram  admin    5 Jun 14 15:24 os.conf
$

Thats why I'm trying to use it.

> Also, I think that passing the pipe character '|' as an argument to
> Popen is not the correct way to use pipes.

I believe subprocess uses pipes as follows
import subprocess
with open("/opt/ldg/etc/channel.conf","w") as out:
  subprocess.Popen(command, stdout=out)

Then the file wouldn't be opened as root? And if the file already
exists then I wouldn't be able to open it due to incorrect
permissions.

> So, if you figure out how to use sudo without '|' you will solve both
> these issues.

I'm open to suggestions as everything I can find involved pipes or
redirections and neither seems to work with subprocess. I can use
subprocess.call() as in:

import subprocess
import sys

channel='stable'
config_file='/opt/ldg/etc/channel.conf'
command="echo -n %s | sudo tee %s > /dev/null" % (channel, config_file)

try:
  retcode = subprocess.call(command, shell=True)
  if retcode < 0:
    sys.exit('Error: Failed to set channel.conf')
except OSError as e:
  sys.exit('Error: Execution failed "%s"' % e)

But I was under the impression that Popen was the preferred approach
to running external processes?

Cheers

Adam



More information about the Python-list mailing list