0

I am executing some commands in a screen over SSH. This works perfectly:

ssh myuser@mydomain.com "screen -list; screen -r -d -X -S myscreen stuff $'echo here\n'"

But now rather than echo, I am trying to run the sed command, which contains double quotes.

sed -i -r "s/(    host: )(\w+)/\1test/" file.yml

The double quotes are causing bash: syntax error near unexpected token `database_name:'

How do I properly escape the double quotes required for sed?

Tim
  • 810
  • 9
  • 20
  • 1
    Why do you need double quotes? This should work with single quotes around your sed command. You don't have anything you want to expand in it. – Benjamin W. Mar 21 '16 at 15:51
  • Single quotes interfere with the single quotes around the stuff command. I am trying to replace echo here with the sed command. – Tim Mar 21 '16 at 15:57
  • You can "quote" single quotes inside other single quotes by using `'\''`. – Etan Reisner Mar 21 '16 at 16:11
  • @EtanReisner: Or `'"'"'` :-) – choroba Mar 21 '16 at 16:18
  • 3
    Try providing the remote commands in a here document to `ssh`, rather than as quoted command-line arguments. It will save you a level of quotes. – chepner Mar 21 '16 at 16:22
  • @choroba `echo 'foo "'" bar'` does not work. You could do that for the outer level double-quotes but not for the inner level single-quotes. – Etan Reisner Mar 21 '16 at 17:21
  • @EtanReisner: You can't escape single quotes inside single-quoted strings. The backslash is Just Another Character(tm). In this case, it works because it is a $'-d string, not a single-quoted string. – rici Mar 21 '16 at 17:33
  • @rici Hm? `echo $'foo "'" bar'` doesn't seem to work for me (nor would I have expected it to). Perhaps I'm missing where `'"'"'` should be used here? The problem is that the OP needs a single quote *inside* the `$'`-quoted string *inside* the outer double-quoted string. – Etan Reisner Mar 21 '16 at 17:45
  • @etan: `echo $'foo\'bar'` will work, but not `echo 'foo\'bar'`. The zipper idiom is `'"'"'` as in `echo 'foo'"'"'bar'`, but not with outer double-quoting. – rici Mar 21 '16 at 17:47
  • @rici Ah, ok. I didn't realize `\'` worked in `$'` quoting. Fun, that. Yeah, `'"'"'` (man typing that is annoying) generally works but is complicated here... then again so is just about anything given the nesting/etc. – Etan Reisner Mar 21 '16 at 17:50
  • @Etan: I was referring to your comment «You can "quote" single quotes inside other single quotes»: that's not correct. You can't, unless the outer single quotes are really $-single-quotes. (Inside double quotes, `'"\'"'` would work, because the innermost `'` is unquoted at that point.) – rici Mar 21 '16 at 17:55
  • @rici Yeah, that's why I used the scare quotes around "quote" there but yes... I probably should have just avoided the word altogether. – Etan Reisner Mar 21 '16 at 17:58
  • 2
    Possible duplicate of [Running shell command that has nested quotes via ssh](http://stackoverflow.com/questions/30234546/running-shell-command-that-has-nested-quotes-via-ssh) – Daniele Segato Mar 21 '16 at 18:25
  • I don't seem to be having any luck with here doc. The following results in -bash: line 2: END: command not found. `ssh myuser@mydomain.com <<'END' screen -list; screen -r -d -X -S myscreen stuff $'echo here\n' END` – Tim Mar 21 '16 at 21:15

1 Answers1

0

I've found the easiest way to do this is by breaking it up into two commands.

First send the command to the screen. Escape any double quotes in the stuff command with a backslash.

ssh myuser@mydomain.com 'screen -list; screen -r -d -X -S myscreen stuff "sed -i -r \"s/(    host: )(\w+)/\1test/\"" file.yml'
                        └────────────────────────────────────────────────────────────────────────────────────────────┘
                                                                         └──────────────────────────────────────┘

Then send a return to execute the command. Note the $ which makes it execute.

ssh myuser@mydomain.com "screen -list; screen -r -d -X -S myscreen stuff $'\n'"
                        └─────────────────────────────────────────────────┘
                                                                          └──┘
Tim
  • 810
  • 9
  • 20