1

I want to add lines to /etc/my.conf as "sudo" using Shell.

Without logging as sudo, I can do:

{ echo "[mysqld]"                                                                                                                                                                                                                                
  echo "default-character-set=utf8"
  echo "character_set_server=utf8"
  echo "[mysql]"
  echo "default-character-set=utf8"
} >> /etc/my.conf

But when:

  sudo   { echo "[mysqld]"                                                                                                                                                                                                                                
  echo "default-character-set=utf8"
  echo "character_set_server=utf8"
  echo "[mysql]"
  echo "default-character-set=utf8"
  } >> /etc/my.conf

I get an error:

 sudo: {: command not found 
 character_set_server=utf8
 [mysql]
 default-character-set=utf8 .....

What am I doing wrong?

ado
  • 1,451
  • 3
  • 17
  • 27
  • The reason this doesn't work is that `{` is not a command, but an element of shell syntax. `sudo` takes commands, not shell script. The general solution to this kind of problem is to use `sh -c`; that lets you make a command whose only operation is to run a little piece of script. – Tom Anderson Jul 05 '13 at 11:55
  • Check http://stackoverflow.com/questions/17396951/run-shell-command-and-send-output-to-file/17397830 – anishsane Jul 05 '13 at 16:03

4 Answers4

8

Firstly, use cat with a here-doc rather than a series of echoes. It's much cleaner. You can use the special form with a dash which strips leading tabs (tabs, not spaces!) to let you indent the here-doc to make it stand out.

Secondly, you can do the redirection as sudo by using sudo sh -c to start a root subshell, in which you then run cat doing the redirection.

Putting it together:

sudo sh -c "cat >>/etc/my.conf" <<-EOF
    [mysqld]
    default-character-set=utf8
    character_set_server=utf8
    [mysql]
    default-character-set=utf8
EOF

I don't know of a more direct way to write a stream to a file as root. It's a shame if there really isn't one.

Tom Anderson
  • 46,189
  • 17
  • 92
  • 133
3

An alternative to launching a new shell is to use the tee command:

{ echo "[mysqld]"                                                                                                                                                                                                                                
  echo "default-character-set=utf8"
  echo "character_set_server=utf8"
  echo "[mysql]"
  echo "default-character-set=utf8"
} | sudo tee -a /etc/my.conf > /dev/null

or

sudo tee -a /etc/my.conf >/dev/null <<-EOF
    [mysqld]
    default-character-set=utf8
    character_set_server=utf8
    [mysql]
    default-character-set=utf8
EOF
chepner
  • 497,756
  • 71
  • 530
  • 681
0
$ sudo echo "foo
bar
baz" > f

should work

  • 2
    It won't, because you're putting the content in the file using a redirection, which is processed by the shell which is running as the user, not one created by sudo. – Tom Anderson Jul 05 '13 at 11:45
0

To make everything easier you should place the commands in a script, and let sudo execute that script.

Francisco
  • 3,980
  • 1
  • 23
  • 27
  • that is ok in generall, but imagine in some parts of your script you have to do RPM packages, you can't do them as sudo, and in other parts you have things like what I showed, modifying conf files, then you need sudo. So I prefer to run it as a normal user, and use sudo inside the script when needed. You might wonder, why this guy wants to put everything in the same shell script.. I just like doing "sh setup" once and let the magic happen.... – ado Jul 05 '13 at 11:50
  • well, I still would find it easier to place all commands that needed sudo (in a row) inside a file and executing that. But I reckon you might prefer to avoid that. – Francisco Jul 05 '13 at 11:55