37

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.

0

3 Answers 3

40

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.

9

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'
4
  • 2
    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, 2011 at 11:00
  • 2
    Using "sudo -E" will preserve the environment variables. Jan 8, 2011 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. Feb 8, 2013 at 15:42
  • 1
    @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, 2013 at 16:00
6

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.

Not the answer you're looking for? Browse other questions tagged .