46

This is the shell command that results in "Permission denied" when I'm trying to append the data in a file to another file with sudo:

sudo cat add_file >> /etc/file

The file at /etc/file is owned by root (i.e. me) and its permissions are rw-r--r--. Should I become root for a moment to make it work or is there a workaround for sudo?

Desmond Hume
  • 8,037
  • 14
  • 65
  • 112
  • 4
    I think this question should be migrated to http://unix.stackexchange.com/ - It is not a programming question. – Ely Dec 26 '15 at 02:02

6 Answers6

69

Run bash as sudo:

$ sudo bash -c "cat add_file >> /etc/file"

$ whoami;sudo bash -c "whoami";whoami
iiSeymour
root
iiSeymour
Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
  • 1
    Can you please explain why `sudo cat add_file >> /etc/file` doesn't work? I don't understand – zhujs Jul 13 '14 at 12:20
  • 1
    Because the file redirection has to be done first. Imagine the case where `sudo cat file` was executed first, the file would be displayed to stdout. When we try to redirect with `>> /etc/file` it would be to late. It's same reason `cat file > file` produces an empty file. – Chris Seymour Jul 13 '14 at 12:25
  • So this is something like `sudo (cat add_file >> etc/file)`, thanks – zhujs Jul 13 '14 at 12:31
27

Try doing this instead :

sudo tee -a /etc/file < add_file

It's lighter than running bash or sh -c command

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • 1
    Maybe lighter but `sudo bash` isn't limited to this specific application, anyway +1 from me. – Chris Seymour Dec 08 '12 at 15:41
  • 2
    The problem with this method (compared to the other ones) is that file `add_file` needs to be readable by the user. But if file is readable by the user, it's shorter and more efficient that launching a whole new `bash` or `sh`. – gniourf_gniourf Dec 08 '12 at 15:41
  • 3
    You may want to use `sudo tee -a /etc/file < add_file > /dev/null` to silence the output to terminal (especially useful if the file being added is large or non text) – AndrewD May 02 '15 at 20:07
9

A funny possibility is to use ed (the standard editor):

sudo ed -s /etc/file <<< $'r add_file\nwq'

I know I won't get upvoted for this wonderful answer, but I wanted to include it here anyway (because it's funny). Done!

gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
5

You are trying to write the result of the command sudo cat add_file to the file /etc/file. And apparently you don't have that right.

man sudo gives that example :

   To make a usage listing of the directories in the /home partition.  Note
   that this runs the commands in a sub-shell to make the cd and file
   redirection work.

    $ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"

So you should try :

sudo sh -c "cat add_file >> /etc/file"

Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75
1

Similar approach to @gniourf_gniourf answer, but using ex:

sudo ex +"r in.txt" -cwq out.txt

which is equivalent to vi/vim Ex-mode (-e).

This in-place edit example is simple, safe and convenient approach, because it doesn't use any shell piping, FIFOs or shell within the shell workarounds.

To boost performance for scripting purposes, consider using silence mode (-s).

Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
-2

try

sudo bash -c 'cat add_file >> /etc/file'

or

cat add_file | sudo tee -a /etc/file > /dev/null
Montells
  • 6,389
  • 4
  • 48
  • 53