How do I use sudo to redirect output to a location I don't have permission to write to?

Your command does not work because the redirection is performed by your shell which does not have the permission to write to /root/test.out. The redirection of the output is not performed by sudo.

There are multiple solutions:

  • Run a shell with sudo and give the command to it by using the -c option:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Create a script with your commands and run that script with sudo:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    Run sudo ls.sh. See Steve Bennett's answer if you don't want to create a temporary file.

  • Launch a shell with sudo -s then run your commands:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • Use sudo tee (if you have to escape a lot when using the -c option):

    sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
    

    The redirect to /dev/null is needed to stop tee from outputting to the screen. To append instead of overwriting the output file (>>), use tee -a or tee --append (the last one is specific to GNU coreutils).

Thanks go to Jd, Adam J. Forster and Johnathan for the second, third and fourth solutions.


Someone here has just suggested sudoing tee:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

This could also be used to redirect any command, to a directory that you do not have access to. It works because the tee program is effectively an "echo to a file" program, and the redirect to /dev/null is to stop it also outputting to the screen to keep it the same as the original contrived example above.


A trick I figured out myself was

sudo ls -hal /root/ | sudo dd of=/root/test.out