344

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?

jtpereyda
  • 2,517
agentofuser
  • 7,677

9 Answers9

482

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
  • 63,447
61

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"
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
  • 28,397
15

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
6

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
5

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
  • 1,037
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
BinaryMisfit
  • 20,879
Bobby
  • 9,032
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
  • 10,412
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
  • 26,615