Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

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

 

 

Python python RSS feed   Index | Next | Previous | View Threaded


ramercer at gmail

Aug 8, 2013, 9:11 PM

Post #1 of 14 (49 views)
Permalink
Using sudo to write to a file as root from a script

Hi

I'm trying to write a script that writes some content to a file root
through sudo, but it's not working at all. I am using:

channel = 'stable'
config_file = '/opt/ldg/etc/channel.conf'
command = ['echo', '-n', channel, '|', 'sudo', 'tee', config_file]
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, _ = p.communicate()

But it seems as if this isn't doing anything.

I just want to write the contents of the variable channel to the file
/opt/ldg/etc/channel.conf. But whatever I try just doesn't work. Can
anyone offer any pointers?

Cheers

Adam
--
http://mail.python.org/mailman/listinfo/python-list


denismfmcmahon at gmail

Aug 8, 2013, 9:36 PM

Post #2 of 14 (48 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Thu, 08 Aug 2013 23:11:09 -0500, Adam Mercer wrote:

> Hi
>
> I'm trying to write a script that writes some content to a file root
> through sudo, but it's not working at all. I am using:
>
> channel = 'stable'
> config_file = '/opt/ldg/etc/channel.conf'
> command = ['echo', '-n', channel, '|', 'sudo', 'tee', config_file]
> p = subprocess.Popen(command, stdout=subprocess.PIPE,
> stderr=subprocess.PIPE)
> out, _ = p.communicate()
>
> But it seems as if this isn't doing anything.
>
> I just want to write the contents of the variable channel to the file
> /opt/ldg/etc/channel.conf. But whatever I try just doesn't work. Can
> anyone offer any pointers?

Do you find anything with:

$ grep sudo /var/log/auth.log

(you may need to specify a different log)

Is the process that's trying to use the sudo command allowed to do so
without a password?

man sudoers

Note - after editing /etc/sudoers you must set the permissions back to 440

--
Denis McMahon, denismfmcmahon [at] gmail
--
http://mail.python.org/mailman/listinfo/python-list


bouncingcats at gmail

Aug 8, 2013, 9:47 PM

Post #3 of 14 (48 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On 9 August 2013 14:11, Adam Mercer <ramercer [at] gmail> wrote:
>
> I'm trying to write a script that writes some content to a file root
> through sudo, but it's not working at all. I am using:

[...]

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.

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

So, if you figure out how to use sudo without '|' you will solve both
these issues.
--
http://mail.python.org/mailman/listinfo/python-list


ishish at domhain

Aug 9, 2013, 1:46 AM

Post #4 of 14 (40 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

Am 09.08.2013 05:47, schrieb David:
> On 9 August 2013 14:11, Adam Mercer <ramercer [at] gmail> wrote:
>>
>> I'm trying to write a script that writes some content to a file root
>> through sudo, but it's not working at all. I am using:
>
> [...]
>
> 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.
>
> Also, I think that passing the pipe character '|' as an argument to
> Popen is not the correct way to use pipes.
>
> So, if you figure out how to use sudo without '|' you will solve both
> these issues.

Or try to change the permissions

os.system("chmod 666 config_file)

do what you want with the file and set the permissions back to their
original state.
--
http://mail.python.org/mailman/listinfo/python-list


ramercer at gmail

Aug 9, 2013, 6:21 AM

Post #5 of 14 (34 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Thu, Aug 8, 2013 at 11:47 PM, David <bouncingcats [at] gmail> 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] cizi ~]$ 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
--
http://mail.python.org/mailman/listinfo/python-list


rosuav at gmail

Aug 9, 2013, 6:29 AM

Post #6 of 14 (34 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Fri, Aug 9, 2013 at 2:21 PM, Adam Mercer <ramercer [at] gmail> wrote:
> command="echo -n %s | sudo tee %s > /dev/null" % (channel, config_file)
>


You shouldn't need to use 'echo' here. Just provide tee with the text
on its standard input, and don't bother with the pipe at all.

ChrisA
--
http://mail.python.org/mailman/listinfo/python-list


antoon.pardon at rece

Aug 9, 2013, 6:42 AM

Post #7 of 14 (33 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

Op 09-08-13 15:29, Chris Angelico schreef:
> On Fri, Aug 9, 2013 at 2:21 PM, Adam Mercer <ramercer [at] gmail> wrote:
>> command="echo -n %s | sudo tee %s > /dev/null" % (channel, config_file)
>>
>
> You shouldn't need to use 'echo' here. Just provide tee with the text
> on its standard input, and don't bother with the pipe at all.

That is probably beside the point. I suspect Adam is just giving a
minimal example to show the kind of thing he is trying to do.

Nit picking the specific example instead of advising on the problem
is likely to be less than helpful.

--
Antoon Pardon
--
http://mail.python.org/mailman/listinfo/python-list


ramercer at gmail

Aug 9, 2013, 6:42 AM

Post #8 of 14 (34 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Fri, Aug 9, 2013 at 8:29 AM, Chris Angelico <rosuav [at] gmail> wrote:

> You shouldn't need to use 'echo' here. Just provide tee with the text
> on its standard input, and don't bother with the pipe at all.

Thanks, that's much better!

Cheers

Adam
--
http://mail.python.org/mailman/listinfo/python-list


ramercer at gmail

Aug 9, 2013, 6:50 AM

Post #9 of 14 (34 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Fri, Aug 9, 2013 at 8:42 AM, Antoon Pardon
<antoon.pardon [at] rece> wrote:

> That is probably beside the point. I suspect Adam is just giving a
> minimal example to show the kind of thing he is trying to do.
>
> Nit picking the specific example instead of advising on the problem
> is likely to be less than helpful.

It is a simplified example, but in this case the nitpicking was very
helpful. Caused me to think about the problem differently, and
therefore come up with a neater solution.

Cheers

Adam
--
http://mail.python.org/mailman/listinfo/python-list


antoon.pardon at rece

Aug 9, 2013, 6:52 AM

Post #10 of 14 (34 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

Op 09-08-13 06:11, Adam Mercer schreef:
> Hi
>
> I'm trying to write a script that writes some content to a file root
> through sudo, but it's not working at all. I am using:
>
> channel = 'stable'
> config_file = '/opt/ldg/etc/channel.conf'
> command = ['echo', '-n', channel, '|', 'sudo', 'tee', config_file]
> p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
> out, _ = p.communicate()
>
> But it seems as if this isn't doing anything.
>
> I just want to write the contents of the variable channel to the file
> /opt/ldg/etc/channel.conf. But whatever I try just doesn't work. Can
> anyone offer any pointers?
>
> Cheers
>
> Adam

subprocess.Popen by default doesn't use a shell. That could mean that
the equivallent shell command you are trying to execute is:

echo -n stable '|' sudo tee /opt/ldg/etc/channel.conf

instead of

echo -n stable | sudo tee /opt/ldg/etc/channel.conf

which you probably want.


You should also take care with the echo command. Echo is
usually a shell builtin that can behave differently than
the echo command. You should make sure you are using the
one you actually want to use.

--
Antoon Pardon
--
http://mail.python.org/mailman/listinfo/python-list


rosuav at gmail

Aug 9, 2013, 8:05 AM

Post #11 of 14 (34 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Fri, Aug 9, 2013 at 2:50 PM, Adam Mercer <ramercer [at] gmail> wrote:
> On Fri, Aug 9, 2013 at 8:42 AM, Antoon Pardon
> <antoon.pardon [at] rece> wrote:
>
>> That is probably beside the point. I suspect Adam is just giving a
>> minimal example to show the kind of thing he is trying to do.
>>
>> Nit picking the specific example instead of advising on the problem
>> is likely to be less than helpful.
>
> It is a simplified example, but in this case the nitpicking was very
> helpful. Caused me to think about the problem differently, and
> therefore come up with a neater solution.

It wasn't nitpicking so much as suggesting a more Pythonic way to do
things. It's entirely plausible that the response would have been
"Actually, the real command is more complicated than 'echo' so I
really do need a pipe", but it's *very* common in shell scripts to
call on an external process to do something that in other languages is
a builtin. For instance, how do you get the name of the parent of your
current directory in bash? Something along the lines of:

parent=$(dirname $(pwd$)$)

which executes two external commands. In Python, it would be:

os.path.dirname(os.getcwd())

which is two internal function calls. It's just one of the things to
consider when porting code from one language to another - I wouldn't
often use a list comprehension in bash, and I wouldn't often want a
pipe between two external processes in Python.

ChrisA
--
http://mail.python.org/mailman/listinfo/python-list


bouncingcats at gmail

Aug 9, 2013, 8:56 AM

Post #12 of 14 (27 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On 9 August 2013 23:21, Adam Mercer <ramercer [at] gmail> wrote:
> On Thu, Aug 8, 2013 at 11:47 PM, David <bouncingcats [at] gmail> 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:

Ah, sorry, I didn't pay close attention to what you are doing (with tee).

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

At least I wasn't 100% wrong :)
Anyway I'm glad some smarter people helped you.
--
http://mail.python.org/mailman/listinfo/python-list


nobody at nowhere

Aug 9, 2013, 1:12 PM

Post #13 of 14 (25 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Thu, 08 Aug 2013 23:11:09 -0500, Adam Mercer wrote:

> I'm trying to write a script that writes some content to a file root
> through sudo, but it's not working at all. I am using:

> command = ['echo', '-n', channel, '|', 'sudo', 'tee', config_file]

You can't create a pipeline like this. All of the list elements after the
first will be passed as arguments to "echo".

Try:

command = ['sudo', 'tee', config_file]
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, _ = p.communicate('channel')

--
http://mail.python.org/mailman/listinfo/python-list


nobody at nowhere

Aug 9, 2013, 1:16 PM

Post #14 of 14 (25 views)
Permalink
Re: Using sudo to write to a file as root from a script [In reply to]

On Fri, 09 Aug 2013 21:12:20 +0100, Nobody wrote:

> Try:
>
> command = ['sudo', 'tee', config_file]
> p = subprocess.Popen(command, stdout=subprocess.PIPE,
> stderr=subprocess.PIPE)
> out, _ = p.communicate('channel')

Oops; you also need stdin=subprocess.PIPE.

--
http://mail.python.org/mailman/listinfo/python-list

Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.