Reputation: 55
I am trying to add an argument to the flag batch start. This is the error it gives me. Any idea on how to fix this?
$ sed -i "s/batch_start.*/batch_start\ 1111/" /tmp/runfile
sed: -e expression #1, char 27: unterminated `s' command
Upvotes: 0
Views: 798
Reputation: 126048
The root problem is that the command is being sent over ssh
; that means it's running through two levels of shell parsing, one on the local computer, then another on the remote computer. That means it goes through quote/escape parsing, application, and removal twice, so you need two "layers" of quoting/escaping.
The command in the last comment doesn't parse (mismatched quotes), but I can reproduce the error message with this command:
ssh remoteHost "sudo sed -i "s/batch_start.*/batch_start\ 1111/" /tmp/runfile"
This sort-of has two levels of quotes, but quotes don't nest, so it doesn't work. The local shell parses this as a double-quoted string "sudo sed -i "
, then an unquoted section s/batch_start.*/batch_start\ 1111/
(which contains an escaped space, so it'll remove the escape), then another double-quoted section: " /tmp/runfile"
. Since there are no spaces between them, they all get passed to ssh
as a single argument. You can see the post-parsing string by replacing ssh remoteHost
with echo
:
$ echo "sudo sed -i "s/batch_start.*/batch_start\ 1111/" /tmp/runfile"
sudo sed -i s/batch_start.*/batch_start 1111/ /tmp/runfile
...so that's the command the remote shell will execute. Since there's a space between s/batch_start.*/batch_start
and 1111/
, they get passed to sed
as separate arguments, and it treats the first as the command to execute (which is missing a close /
) and the second as a filename.
Solution: there are many ways to correct the quoting. You can use the echo
trick to see what'll get sent to the remote shell. I tend to prefer single-quotes around the entire command, and then just quote normally inside that (as long as the inner command doesn't itself contain single-quotes). In this case, that means:
ssh remoteHost 'sudo sed -i "s/batch_start.*/batch_start 1111/" /tmp/runfile'
which executes this on the remote computer:
sudo sed -i "s/batch_start.*/batch_start 1111/" /tmp/runfile
(note that I removed the escape on the space.)
Upvotes: 1