I've been given sudo access on one of our development RedHat linux boxes, and I seem to find myself quite often needing to redirect output to a location I don't normally have write access to.
The trouble is, this contrived example doesn't work:
sudo ls -hal /root/ > /root/test.out
I just receive the response:
-bash: /root/test.out: Permission denied
How can I get this to work?
This question is related to
linux
permissions
sudo
io-redirection
permission-denied
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.
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
This is based on the answer involving tee
. To make things easier I wrote a small script (I call it suwrite
) and put it in /usr/local/bin/
with +x
permission:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$@" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
sudo tee "$@" > /dev/null
As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo
).
echo test | suwrite /root/test.txt
Note that since this is a simple wrapper for tee
, it will also accept tee's -a
option to append, and also supports writing to multiple files at the same time.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
It also has some simplistic protection against writing to /dev/
devices which was a concern mentioned in one of the comments on this page.
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
The problem is that the command gets run under sudo
, but the redirection gets run under your user. This is done by the shell and there is very little you can do about it.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
The usual ways of bypassing this are:
Wrap the commands in a script which you call under sudo.
If the commands and/or log file changes, you can make the script take these as arguments. For example:
sudo log_script command /log/file.txt
Call a shell and pass the command line as a parameter with -c
This is especially useful for one off compound commands. For example:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
Don't mean to beat a dead horse, but there are too many answers here that use tee
, which means you have to redirect stdout
to /dev/null
unless you want to see a copy on the screen.
A simpler solution is to just use cat
like this:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo
instead of the one running it.
A trick I figured out myself was
sudo ls -hal /root/ | sudo dd of=/root/test.out
The way I would go about this issue is:
If you need to write/replace the file:
echo "some text" | sudo tee /path/to/file
If you need to append to the file:
echo "some text" | sudo tee -a /path/to/file
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
Yet another variation on the theme:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Or of course:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
They have the (tiny) advantage that you don't need to remember any arguments to sudo
or sh
/bash
Yet another variation on the theme:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Or of course:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
They have the (tiny) advantage that you don't need to remember any arguments to sudo
or sh
/bash
Clarifying a bit on why the tee option is preferable
Assuming you have appropriate permission to execute the command that creates the output, if you pipe the output of your command to tee, you only need to elevate tee's privledges with sudo and direct tee to write (or append) to the file in question.
in the example given in the question that would mean:
ls -hal /root/ | sudo tee /root/test.out
for a couple more practical examples:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
In each of these examples you are taking the output of a non-privileged command and writing to a file that is usually only writable by root, which is the origin of your question.
It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo
but when the source command is a script that you don't completely trust, it is crucial.
Note you can use the -a option to tee to append append (like >>
) to the target file rather than overwrite it (like >
).
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
Clarifying a bit on why the tee option is preferable
Assuming you have appropriate permission to execute the command that creates the output, if you pipe the output of your command to tee, you only need to elevate tee's privledges with sudo and direct tee to write (or append) to the file in question.
in the example given in the question that would mean:
ls -hal /root/ | sudo tee /root/test.out
for a couple more practical examples:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
In each of these examples you are taking the output of a non-privileged command and writing to a file that is usually only writable by root, which is the origin of your question.
It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo
but when the source command is a script that you don't completely trust, it is crucial.
Note you can use the -a option to tee to append append (like >>
) to the target file rather than overwrite it (like >
).
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
The problem is that the command gets run under sudo
, but the redirection gets run under your user. This is done by the shell and there is very little you can do about it.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
The usual ways of bypassing this are:
Wrap the commands in a script which you call under sudo.
If the commands and/or log file changes, you can make the script take these as arguments. For example:
sudo log_script command /log/file.txt
Call a shell and pass the command line as a parameter with -c
This is especially useful for one off compound commands. For example:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
I would do it this way:
sudo su -c 'ls -hal /root/ > /root/test.out'
This is based on the answer involving tee
. To make things easier I wrote a small script (I call it suwrite
) and put it in /usr/local/bin/
with +x
permission:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$@" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
sudo tee "$@" > /dev/null
As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo
).
echo test | suwrite /root/test.txt
Note that since this is a simple wrapper for tee
, it will also accept tee's -a
option to append, and also supports writing to multiple files at the same time.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
It also has some simplistic protection against writing to /dev/
devices which was a concern mentioned in one of the comments on this page.
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
The way I would go about this issue is:
If you need to write/replace the file:
echo "some text" | sudo tee /path/to/file
If you need to append to the file:
echo "some text" | sudo tee -a /path/to/file
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
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.
Don't mean to beat a dead horse, but there are too many answers here that use tee
, which means you have to redirect stdout
to /dev/null
unless you want to see a copy on the screen.
A simpler solution is to just use cat
like this:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo
instead of the one running it.
Yet another variation on the theme:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Or of course:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
They have the (tiny) advantage that you don't need to remember any arguments to sudo
or sh
/bash
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.
The way I would go about this issue is:
If you need to write/replace the file:
echo "some text" | sudo tee /path/to/file
If you need to append to the file:
echo "some text" | sudo tee -a /path/to/file
The problem is that the command gets run under sudo
, but the redirection gets run under your user. This is done by the shell and there is very little you can do about it.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
The usual ways of bypassing this are:
Wrap the commands in a script which you call under sudo.
If the commands and/or log file changes, you can make the script take these as arguments. For example:
sudo log_script command /log/file.txt
Call a shell and pass the command line as a parameter with -c
This is especially useful for one off compound commands. For example:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
I would do it this way:
sudo su -c 'ls -hal /root/ > /root/test.out'
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
Yet another variation on the theme:
sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
Or of course:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
They have the (tiny) advantage that you don't need to remember any arguments to sudo
or sh
/bash
A trick I figured out myself was
sudo ls -hal /root/ | sudo dd of=/root/test.out
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.
The way I would go about this issue is:
If you need to write/replace the file:
echo "some text" | sudo tee /path/to/file
If you need to append to the file:
echo "some text" | sudo tee -a /path/to/file
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
Clarifying a bit on why the tee option is preferable
Assuming you have appropriate permission to execute the command that creates the output, if you pipe the output of your command to tee, you only need to elevate tee's privledges with sudo and direct tee to write (or append) to the file in question.
in the example given in the question that would mean:
ls -hal /root/ | sudo tee /root/test.out
for a couple more practical examples:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
In each of these examples you are taking the output of a non-privileged command and writing to a file that is usually only writable by root, which is the origin of your question.
It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo
but when the source command is a script that you don't completely trust, it is crucial.
Note you can use the -a option to tee to append append (like >>
) to the target file rather than overwrite it (like >
).
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
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.
The problem is that the command gets run under sudo
, but the redirection gets run under your user. This is done by the shell and there is very little you can do about it.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
The usual ways of bypassing this are:
Wrap the commands in a script which you call under sudo.
If the commands and/or log file changes, you can make the script take these as arguments. For example:
sudo log_script command /log/file.txt
Call a shell and pass the command line as a parameter with -c
This is especially useful for one off compound commands. For example:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
A trick I figured out myself was
sudo ls -hal /root/ | sudo dd of=/root/test.out
Make sudo run a shell, like this:
sudo sh -c "echo foo > ~root/out"
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
This is based on the answer involving tee
. To make things easier I wrote a small script (I call it suwrite
) and put it in /usr/local/bin/
with +x
permission:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$@" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
sudo tee "$@" > /dev/null
As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo
).
echo test | suwrite /root/test.txt
Note that since this is a simple wrapper for tee
, it will also accept tee's -a
option to append, and also supports writing to multiple files at the same time.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
It also has some simplistic protection against writing to /dev/
devices which was a concern mentioned in one of the comments on this page.
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017
A trick I figured out myself was
sudo ls -hal /root/ | sudo dd of=/root/test.out
This is based on the answer involving tee
. To make things easier I wrote a small script (I call it suwrite
) and put it in /usr/local/bin/
with +x
permission:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$@" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
sudo tee "$@" > /dev/null
As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo
).
echo test | suwrite /root/test.txt
Note that since this is a simple wrapper for tee
, it will also accept tee's -a
option to append, and also supports writing to multiple files at the same time.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
It also has some simplistic protection against writing to /dev/
devices which was a concern mentioned in one of the comments on this page.
I would do it this way:
sudo su -c 'ls -hal /root/ > /root/test.out'
Don't mean to beat a dead horse, but there are too many answers here that use tee
, which means you have to redirect stdout
to /dev/null
unless you want to see a copy on the screen.
A simpler solution is to just use cat
like this:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo
instead of the one running it.
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.
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
Clarifying a bit on why the tee option is preferable
Assuming you have appropriate permission to execute the command that creates the output, if you pipe the output of your command to tee, you only need to elevate tee's privledges with sudo and direct tee to write (or append) to the file in question.
in the example given in the question that would mean:
ls -hal /root/ | sudo tee /root/test.out
for a couple more practical examples:
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
In each of these examples you are taking the output of a non-privileged command and writing to a file that is usually only writable by root, which is the origin of your question.
It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo
but when the source command is a script that you don't completely trust, it is crucial.
Note you can use the -a option to tee to append append (like >>
) to the target file rather than overwrite it (like >
).
Don't mean to beat a dead horse, but there are too many answers here that use tee
, which means you have to redirect stdout
to /dev/null
unless you want to see a copy on the screen.
A simpler solution is to just use cat
like this:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo
instead of the one running it.
Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)
If it is not the case then maybe you can write bash script:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Press ctrl + d :
chmod a+x myscript.sh
sudo myscript.sh
Hope it help.
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.
Whenever I have to do something like this I just become root:
# sudo -s
# ls -hal /root/ > /root/test.out
# exit
It's probably not the best way, but it works.
How about writing a script?
Filename: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Then use sudo to run the script:
sudo ./myscript
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.
I would do it this way:
sudo su -c 'ls -hal /root/ > /root/test.out'
Source: Stackoverflow.com