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.

When you attempt to modify a file without having write permissions on it, you get an error:

> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo

Sudoing doesn't help, because it runs the command as root, but the shell handles redirecting stdout and opens the file as you anyway:

> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo

Is there an easy way to redirect stdout to a file you don't have permission to write to, besides opening a shell as root and manipulating the file that way?

> sudo su
# echo test > /tmp/foo
share|improve this question
1  
Answer for a similar question from StackOverflow stackoverflow.com/questions/82256/… –  Cristian Ciupitu Sep 3 '10 at 11:22

5 Answers 5

up vote 50 down vote accepted

Yes, using tee. So echo test > /tmp/foo becomes

echo test | sudo tee /tmp/foo

You can also append (>>)

echo test | sudo tee -a /tmp/foo
share|improve this answer
11  
Tee will also output to stdout; sometimes you don't want the contents filling the screen. To fix this, do echo test | sudo tee /tmp/foo > /dev/null –  Shawn J. Goff Dec 14 '10 at 15:20
    
Oh hey, there's an app for that! –  Mehrdad Jul 19 '11 at 3:49
echo test | sudo dd of=/tmp/foo
share|improve this answer

tee is surely a good choice, but how about this?

sudo -i eval "echo test > /tmp/foo"

EDIT: as per hop's comment, there is a better way

sudo sh -c "echo test > /tmp/foo"
share|improve this answer
    
3 problems: eval instead of a simple sh -c; -i, which will change your working dir; running the whole command as root, which might change it's behaviour or may introduce an unnecessary risk. why did this ever get an upvote? –  hop Aug 31 '10 at 10:38
    
I don't know why you seem to be annoyed by the upvote. Sure there can be bugs in my answers, I didn't say mine is the best, did I? –  phunehehe Aug 31 '10 at 16:47
3  
you didn't, but it is misleading, generally bad and maybe even dangerous. –  hop Aug 31 '10 at 20:24
    
COME ON! I fixed it, OK? What's the point of sacrificing you 1 rep for something that's already fixed? –  phunehehe Dec 15 '10 at 3:16

While I agree, that | sudo tee is the canonical way, sometimes sed may work:

cat sudotest 
line 1

sudo sed -i 'i1itest' sudotest && cat sudotest 
1itest
line 1

sudo sed -i '$aatest' sudotest && cat sudotest 
1itest
line 1
atest

-i modifies the file in place. i1 means 'insert before line 1'. $a means append after last line.

Or copy to xclipboard:

somecommand | xclip
sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
share|improve this answer

I have been kicking around in the back of my mind ideas for a similar problem, and came up with the following solutions:

  • sudo uncat where uncat is a program that reads standard input and writes it to the file named on the command line, but I haven't written uncat yet.

  • sudocat the variant of sudoedit that i haven't written yet that does a cleaner sudo cat or sudo uncat.

  • or this little trick of using sudoedit with an EDITOR that is a shell script
    #!/bin/sh
    # uncat
    cat > "$1"

which can be invoked as either |sudo ./uncat file or | EDITOR=./uncat sudoedit but that has interesting side-effects.

share|improve this answer

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.