The proper use of redirection with sudo.

[ad#Google Adsense-1]
We are faced with a problem when trying to redirect with sudo, as the second part of the command is not executed with root privileges.
sudo command > outputfile
<>—-root——<>—user—<>
The solution is to use;
‘sudo tee’ instead of the ‘>’ operator,
‘sudo tee -a’ instead of the ‘>>’ operator.
sudo command | sudo tee outputfile
<>—–root—–<>——-root——<>
The problem can be seen using a simple demonstration:

petur@laptop:/tmp$ sudo date > output
petur@laptop:/tmp$ ls -l
total 4
-rw-r--r-- 1 petur petur 30 2010-07-06 23:14 output
petur.petur is the owner of the output file.

petur@laptop:/tmp$ rm output


petur@laptop:/tmp$ sudo date | sudo tee output
Tue Jul 6 23:15:31 CEST 2010
petur@laptop:/tmp$ ls -l
total 4
-rw-r--r-- 1 root root 30 2010-07-06 23:15 output
root.root is the owner of the output file.
[ad#Google Adsense-1]

10 Replies to “The proper use of redirection with sudo.”

  1. Why don’t you just redirect to output to somewhere your own user has write access to?
    On a system with restricted sudo access (i.e. only well chosen commands are available to you), this will of course not work, as you could overwrite any file of your choice using tee.

  2. Also: sudo bash -c “date > output2”
    Using tee does has the advantage of console output on the display — but you did say “redirection with sudo”.

  3. Ok, but the article doesn’t explain why “$ sudo command > outputfile” writes output file as normal user and not as sudo. It remains obscure for me. I’d appreciate an explication. Thank you!

    1. The redirection of the output is performed by the shell, not sudo.
      sudo merely executes the command as root and sends the output of that command back to the shell, then it’s up to the shell (which is running as your user) to handle the output.
      >> or > tells the shell to redirect the output to a file (rather than displaying it on the current terminal), and it will do that using your credentials.

  4. Another way to do it, if you don’t want the first command’s output to be displayed, is
    $ sudo command | sudo dd of=outputfile

  5. Thanks for this tip. It is very useful.
    Slightly off topic but on a similar theme, do you have any idea about how to deal with the error levels returned from these complex commands? That is, given:
    sudo command | sudo tee output
    how to check the error level of each sudo command (eg user doesn’t have permission in sudoers, command not found), independently from return values from command and tee?
    I’m trying to write a service start script to handle:
    nice sudo user command
    It’s normally run as root but if not then nice will complain if the level is negative. Sudo and command each have their own return values. How would you write a script to execute nested commands and check each component’s return values?
    I hope you’re up for a challenge 🙂

Leave a Reply