Note your ssh
command line, the part with the sed
command sent to the other end:
ssh ... "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile"
^^^^^^^^^..................................................^^^^^^^^^^^^^^^^^^
You have two quoted strings here, the ones marked with ^
. The rest in the middle is not quoted, and that includes the variable expansion $oldlogsdate
. Since it's unquoted, it's subject to word splitting, and Apr 7
becomes the two words Apr
and 7
. See also: When is double-quoting necessary?
Now, ssh
is smart enough to glue them back together, but by now the original amount of whitespace is lost, and it just adds a single space.
This is somewhat similar to how the shell forgets the original amount of whitespace in this and echo
glues the words together with a single space:
$ echo hello world
hello world
But note that with SSH, a single level of quotes doesn't help, since SSH passes the command line for the shell on the remote end to interpret, and in that shell too, extra whitespace between words is lost.
So this still doesn't work:
$ ssh localhost echo "hello world"
hello world
(the local shell removes the quotes, and ssh
gets echo
and hello world
, and passes to the remote echo hello world
, which works as above.)
and we actually have to do quoting for both ends to keep the string intact:
$ ssh localhost 'echo "hello world"'
hello world
Actually, it would be better to use printf ":%s\n" hello world
etc. to show more properly where the words break, but the result is similar.
Switching the quotes so that the double-quotes are the outermost lets the local shell expand the variable, and leaves the single quotes for the remote, which minimizes the amount of expansions it does. You'll still need to backslash-escape any double-quotes you want to send to the other side.
$ greeting="hello world"
$ ssh localhost "echo '$greeting'"
hello world
That should work as long as the variable doesn't contain single-quotes itself. If it does, things get uglier, see: Escape a variable for use as content of another script
I think the command line in @sasha's answer looks like it should work for your case.
See also, e.g. this question: Quoting in ssh $host $FOO and ssh $host "sudo su user -c $FOO" type constructs
The question at hand there has one more layer of processing, but the answers seem to apply for the "easier" case too.
$var
,$(cmd)
,$((arith))
) unquoted and involves the$IFS
special parameter. – Stéphane Chazelas Apr 27 '21 at 11:47