How to append to a file as sudo?

285

64

I want to do:

echo "something" >> /etc/config_file

But, since only the root user has write permission to this file, I can't do that. But the following also doesn't work.

sudo echo "something" >> /etc/config_file

Is there a way to append to a file in that situation without having to first open it with a sudo'd editor and then appending the new content by hand?

Helder S Ribeiro

Posted 2010-05-01T05:50:00.433

Reputation: 5 997

Strongly related: Redirecting stdout to a file you don't have write permission on (on Unix & Linux).   Weakly related: ls with directory path shows files, but ls with file pattern does not?

– Scott – 2015-08-28T12:47:06.883

I am using Ubuntu 9.04 and am able to use sudo for every command I've needed to so far. Spawning a sub-shell worked. – Matt Norris – 2009-10-13T14:57:09.367

Answers

408

Use tee -a (or tee --append) with sudo

tee - read from standard input and write to standard output and files
[...]
   -a, --append
      append to the given FILEs, do not overwrite
[...]

So your command becomes

echo "something" | sudo tee -a /etc/config_file

The advantages of tee over executing Bash with administrative permissions are

  • You do not execute Bash with administrative permissions
  • Only the 'write to file' part runs with advanced permissions
  • Quoting of a complex command is much easier

akira

Posted 2010-05-01T05:50:00.433

Reputation: 52 754

Debian 8 tee has the -a append flag. – clay – 2017-03-13T18:46:32.170

11Use echo "output" | sudo tee -a file > /dev/null if you want to skip console output. – Moshe Bixenshpaner – 2017-09-22T01:16:30.310

Works well for WSL as well. – kayleeFrye_onDeck – 2017-12-08T00:18:24.083

2On OS X tee only seems to have an -a flag. – Lri – 2012-06-20T14:48:40.070

51

The redirection is executed in the current shell. In order to do the redirection with elevated privileges, you must run the shell itself with elevated privileges:

sudo bash -c "somecommand >> somefile"

Ignacio Vazquez-Abrams

Posted 2010-05-01T05:50:00.433

Reputation: 100 516

26

Have sudo spawn a sub-shell:

sudo sh -c "echo 'JAVA_HOME=/usr/lib/jvm/java-6-sun' >> /etc/profile"

In this example, sudo runs "sh" with the rest as arguments.

(this is shown as an example in the sudo man page)

Doug Harris

Posted 2010-05-01T05:50:00.433

Reputation: 23 578

This is not the right answer. This is a right answer. Akira's got a better one, for the logic provided in that answer. – TOOGAM – 2016-06-16T17:42:39.653

8The reason is that it's your shell (running as you) that does the redirection, not sudo. Since you don't have permission to write to the file, you get the Permission denied error. What this answer does is to start a new shell that is running as root, and therefore is able to write to the file. – Randy Orrison – 2009-10-13T14:48:31.783

6

I usually use shell HERE document with sudo tee -a. Something along the lines of:

sudo tee -a /etc/profile.d/java.sh << 'EOF'
# configures JAVA
JAVA_HOME=/usr/lib/jvm/java-8-oracle
export JAVA_HOME
export PATH=$PATH:$JAVA_HOME/bin
EOF

Nicholas Sushkin

Posted 2010-05-01T05:50:00.433

Reputation: 161

4

In my opinion, the best in this case is dd:

sudo dd of=/etc/profile <<< END
JAVA_HOME=/usr/lib/jvm/java-6-sun
END

user316693

Posted 2010-05-01T05:50:00.433

Reputation: 41

3

There may be a problem with the sudo here and the redirecting. Use a texteditor of your choice instead to add the line.

sudo nano /etc/profile

Or, you could try su instead

su
echo ‘JAVA_HOME=/usr/lib/jvm/java-6-sun’ >> /etc/profile
exit

Bobby

Posted 2010-05-01T05:50:00.433

Reputation: 8 534

That's fantastic. Now do this as part of a script. – Ernie Dunbar – 2018-05-09T16:02:24.903

Unfortunately, this produced the same result. – Matt Norris – 2009-10-13T14:57:39.630

1su -c 'echo "JAVA_HOME=/usr/lib/jvm/java-6-sun" >> /etc/profile' should work. since there's nothing the shell can mistakenly expand in the arg to echo, single-quote the overall command. – quack quixote – 2009-10-13T15:55:32.107

0

This is very simple and puts sudo first, as it is common.

sudo sed -i '$a something' /etc/config_file

$a means to append at the end of the file.

antonio

Posted 2010-05-01T05:50:00.433

Reputation: 647

0

This won't work you are trying to redirect (using >>) the output of sudo. What you really want to do is redirect the output of echo. I suggest you simply use your favorite editor and add that line manually to /etc/profile. This has the additional benefit that you can check whether /etc/profile already sets JAVA_HOME.

innaM

Posted 2010-05-01T05:50:00.433

Reputation: 9 208

0

Use ex-way:

sudo ex +'$put =\"FOO\"' -cwq /etc/profile

and replace FOO with your variable to append.

In some systems (such as OS X), the /etc/profile file has 444 permissions, so if you still getting permission denied, check and correct the permission first:

sudo chmod 644 /etc/profile

then try again.

kenorb

Posted 2010-05-01T05:50:00.433

Reputation: 16 795