Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

This question already has an answer here:

I have a small question regarding using sudo with output redirect >. To enable IP forwrding, someone can use the command:

echo 1 > /proc/sys/net/ipv4/ip_forward

Executing this command will give permission denied as it requires root privileges. However, executing the same command with sudo gives also permission denied error! It seems that output redirect > does not inherit the permissions of the preceding command echo. Is this right?

As a workaround I do:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Is this the best way to do it? Am I missing something?

Please, note that this is an example and it applies to all commands that use output redirect.

share|improve this question

marked as duplicate by Eliah Kagan, Radu Rădeanu, Pandya, Sylvain Pineau, Eric Carvalho Sep 20 at 14:12

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3 Answers 3

up vote 20 down vote accepted

Your approach with sudo tee is fine. A nice consequence of using sudo tee is that the executed command before the pipe will not run as root. That's useful if you just need the output of a program, which does not require root privileges.

If you don't care about the output of the program used before the pipe (echo 1 in this case), redirect stdout to /dev/null:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null

The above is equivalent to sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward' with the difference that echo 1 is run as root.

If you need to append to a privileged file, you can either use sh -c 'echo 127.0.0.1 local.host >> /etc/hosts' or:

echo 127.0.0.1 local.host | sudo tee -a /etc/hosts

Note the -a which is shorthand for --append.

share|improve this answer

One solution is to use :

sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

but this one doesn't inherit env properties from the parent shell, so you can't use it for example with echo $PATH to get the same result you'd have in your parent shell (of course only in case you alter your path property) .

Using sudo -E will preserve the environment variables.

Also, according to https://wiki.ubuntu.com/DashAsBinSh, you'd be better off using sh (which is a symlink to dash), instead of invoking this with bash.

So, you might rewrite this as :

sudo -E sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
share|improve this answer
1  
You don't need bash for this job, you'd better to use sh (symlink to dash). See wiki.ubuntu.com/DashAsBinSh for differences between these. –  Lekensteyn Jan 8 '11 at 11:00
1  
Using "sudo -E" will preserve the environment variables. –  João Pinto Jan 8 '11 at 11:29
1  
@Lekensteyn You're right sh will do it for this command, but occasionally a command a user runs behaves differently due to bash's additional functionality. I think it's reasonable to recommend bash for users who don't know about the differences. The linked documentation does not say sh should be used instead of bash for interactive purposes. –  Eliah Kagan Feb 8 '13 at 15:42
    
@EliahKagan What command have you seen go wrong when using sh -c instead of bash -c? Granted, bash has features which are incompatible with dash (some forms of variable expansion or brace-globbing for example), but in most cases you will at most have a simple redirection. I do not recommend sh for interactive purposes (input/response), for that bash is better suited. –  Lekensteyn Feb 8 '13 at 16:00

I usually use the sudo bash -c trick, or just do sudo -s first to stay root, then run the redirection command.

The reason it doesn't work the first way is that the shell processes the redirection first, then runs sudo. Since your shell doesn't have access to the file, the redirection fails.

share|improve this answer

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