6

I came across this weird problem just now and I can't seem to get to the bottom of it. I'm trying to add a config file to /etc/sudoers.d/ but get permission denied. In the example below, the file "tweedle" doesn't exist and:

drwxr-xr-x  2 root root   4.0K Jan  2 18:27 sudoers.d/

So here's the command:

$ sudo echo "tweedle ALL=(ALL) ALL" > /etc/sudoers.d/tweedle
-bash: /etc/sudoers.d/tweedle: Permission denied

It doesn't even work when I break it into two commands:

$ sudo touch /etc/sudoers.d/tweedle
$ sudo echo "poodle" > /etc/sudoers.d/tweedle

When I tested it locally, same problem:

$ cd ~
$ mkdir -m 755 tweedle
$ sudo chown root:root tweedle
$ sudo echo "battle" > ~/tweedle/beetle
-bash: /home/spanky/tweedle/beetle: Permission denied
$ sudo touch tweedle/beetle
$ sudo echo "battle" > tweedle/beetle
-bash: tweedle/beetle: Permission denied

Without sudo, all is well:

$ cd ~
$ mkdir poodle
$ echo "noodle" > poodle/bottle
$ cat poodle/bottle
noodle

Thoughts?

Spanky
  • 5,608
  • 10
  • 39
  • 45
  • Quite correct, although searching did not get me there. Thanks. – Spanky Jan 03 '14 at 02:44
  • What you are telling the shell is "Run sudo ...; the output from that command please write to the end of `sudoers`. Note that the writing is done *outside* of the command executed by `sudo`, with your privileges (i.e., not allowed to write that file). There should be a command like `visudo(1)` available to edit the file securely. – vonbrand Mar 06 '14 at 00:49
  • Duplicate of https://stackoverflow.com/questions/84882/ – dskrvk Apr 13 '18 at 00:37

2 Answers2

16

The echo command is being run as root, but the redirection is done by your shell, so it's executed as the current user, not as root.

The simplest solution is to invoke a root shell to run both the command and the redirection.

Rather than:

sudo echo line > file

try this:

sudo sh -c 'echo line > file'

or

sudo bash -c 'echo line > file'
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • Dude, "The echo command is being run as root, but the redirection is done by your shell, so it's executed as the current user, not as root." -- that just saved the day here, thanks :) – the_marcelo_r Feb 18 '15 at 14:52
7

The answer is to use "tee" with a pipe, a command I wasn't familiar with, so you can use sudo for the second half:

$ echo "tweedle ALL=(ALL) ALL" | sudo tee /etc/sudoers.d/tweedle
Spanky
  • 5,608
  • 10
  • 39
  • 45
  • 1
    an interesting workaround but @Keith's answer is way more idiomatic – qwwqwwq Jan 03 '14 at 03:11
  • I'm building up a lot of lines in a shell script string variable which I then append to a file. This method saves me from figuring out how to expand that variable in the argument to sh -c . – steamer25 May 05 '15 at 15:21