Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

i have written a function which acts in a similar way to tee but also pre-pends a datestamp. everything works fine except when i want to output to a file which is only root writeable (in my case a logfile within /var/log). i've simplified the following code snippet to just include the bits which are not working:

#!/bin/bash
#script ~/test_logger.sh
logfile=/var/log/test.log
logger()
{
    while read data
    do
        echo $data >> $logfile
    done
    return 0
}
sudo ls ~ | logger

it works fine if i run the whole script like so sudo ~/test_logger.sh but i can't always do this since i want to use the logger function in files like ~/.bash_logout which are run automatically. i've tried putting sudo in front of the echo in the while loop but this does not work. any ideas?

share|improve this question
add comment

4 Answers 4

up vote 7 down vote accepted

it's generally bad practice to put sudo in a script. A better choice would be to call the script with sudo from ~/.bash_logout or wherever else you want to use it, if you must, or better still just make /var/log/test.log world-writable.

share|improve this answer
    
yes! i put the whole script into a new file test_logger.sh, made it executeable, then ran it from ~/.bash_logout like so: sudo ~/.bash_logout. works great :) –  mulllhausen Mar 7 '11 at 6:55
add comment

as you've found, sudo command >out doesn't work because 'command' is run by sudo, but '>out' is a function of the shell, not 'command'. So, you need to escalate the shell itself:

sudo sh -c "echo $data >>$logfile"

note that you want to be really, really sure what's in $data doing this:

~$ export data='good; touch /tmp/reallybad'
~$ echo $data
good; touch /tmp/reallybad
~$ sudo sh -c "echo $data>>/tmp/happy"
good
~$ ls /tmp/happy /tmp/reallybad
/tmp/happy  /tmp/reallybad

hence simon's warning.

share|improve this answer
    
ah thanks for clarifying the possibilities of [pipe-injection?]. i think the way i ended up doing it (see the comment under simon's solution) is safe since there is no opportunity for anyone to splice extra commands into my ~/.bash_logout file (unless the entire system is already compromised obviously) –  mulllhausen Mar 7 '11 at 6:59
add comment

sudo does not work in the way you might think when you use redirection or pipe operators. The stream change is not executed with sudo permissions. This is why

sudo echo foo >> bar

will not work if bar is only root-writable.

When you run the script under sudo, everything in the script gets superuser permissions so it works correctly in that circumstance.

A workaround is to do this to make sure the writing command is run under sudo:

sudo echo foo | sudo tee bar > /dev/null

Bear in mind, however, that this does not append to the file. It overwrites the file.

share|improve this answer
    
this doesnt work for me - i tried your second command like so sudo echo hi | sudo tee /var/log/test.log > /dev/null but it just continuously prompts for the sudo password. –  mulllhausen Mar 7 '11 at 6:01
    
Do you have sudo set-up to prompt for password every time it is used? My configuration allows continuous use of sudo as long as it was successfully used in the last 2~3 minutes so it only prompts for the sudo before the pipe. –  Puddingfox Mar 10 '11 at 17:41
add comment

Well if you take a look at the man page of sudo you can see examples of how to use it in the scripts... the -c option lets execute a command.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.