1

I'm trying to append a string to a file in a docker container using docker exec. However, it doesn't seem to interpret properly the ">>" operator

 sudo docker exec --interactive mycontainer cat /etc/postfix/main.cf

returns

smtpd_banner = $myhostname ESMTP $mail_name (Debian)
biff = no
append_dot_mydomain = no
readme_directory = no

# Basic configuration
# myhostname =
...

But

sudo docker exec --interactive mycontainer echo "my new line" >> /etc/postfix/main.cf

returns -bash: /etc/postfix/main.cf: No such file or directory

Either way there is a trick to pass in the ">>" operator to docker-exec, or there is another command to append a string to a file (which would be OK aswell, but I couldn't find one that is native, because containers do not have any fancy librairies).

Has anyone a trick ?

Arthur Attout
  • 2,701
  • 2
  • 26
  • 49
  • Oops sorry, will fix that – Arthur Attout May 19 '18 at 00:39
  • You need to run a shell in docker to interpret operators. `echo` is not a shell. Run something like `bash` instead and execute `echo` inside that. – Paul May 19 '18 at 00:44
  • @ArthurAttout you need to provide bash type and -c option for command, try this it should work `sudo docker exec -i -t mycontainer /bin/bash -c 'echo my new line>>/etc/postfix/main.cf'` – Mahattam May 19 '18 at 09:59

1 Answers1

1

You're running the sudo command in a shell, and it is interpreting the >> before it ever reaches sudo or the docker client. You need to escape or quote the characters so your own shell doesn't interpret them, and then you need to run a shell inside the docker container to interpret them:

sudo docker exec -i mycontainer \
  /bin/sh -c 'echo "my new line" >> /etc/postfix/main.cf'

To pass variables from the outer shell to inside the container, you won't be able to use single quotes. You can use double quotes and escape anything you want to pass to the inner shell.

sudo docker exec -i mycontainer \
  /bin/sh -c "echo \"$host_var \$container_var\" >> /etc/postfix/main.cf"
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Thanks for the tip, it worked ! Why do I need /bin/sh ? Is it just to interpret the ">>" ? – Arthur Attout May 19 '18 at 12:01
  • The `/bin/sh` is the shell being run inside the container. You need that to interpret shell commands like the i/o redirection. – BMitch May 19 '18 at 12:32
  • Sorry to dig up my old question but I'm facing another issue regarding this. How can I put a variable inside "my new line" ? From what I understand, if I try "my new var $var" the $var will be evaluated by the shell inside the container, which doesn't know about $var. What can I do ? I tried creating the string before the instruction, and popping it into docker exec, but it is still evaluated by the distant shell – Arthur Attout May 22 '18 at 14:52
  • I've updated the answer with more details on quoting and escaping values inside the quotes to achieve your goal. – BMitch May 22 '18 at 20:12
  • @ArthurAttout An alternative to double quotes is to still use single quotes except switch to double around the variable. I find this a bit easier to read since you don't need to escape anything: `/bin/sh -c 'echo '"$host_var"' $container_var >> /etc/postfix/main.cf'` – Paul May 22 '18 at 21:05
  • Ow, did not think about escaping quotes .. Thanks for the tip ! – Arthur Attout May 22 '18 at 22:16