Como as edições finais foram reveladas, o problema não está relacionado ao cifrão, mas é causado pelo conteúdo de deststr
, que não é 192.168.1.3 192.168.1.4
, mas sim duas linhas, uma contendo apenas 192.168.1.3
e a outra contendo apenas 192.168.1.4
, ambas as linhas terminadas com um caractere de nova linha. Ou seja, o comando real após a substituição da variável é:
sed "25s/Allow from .*/Allow from 192.168.1.3
192.168.1.4
/" -i test2
Agora, sed
interpreta seu comando linha por linha e, assim, o primeiro comando que ele tenta interpretar é:
25s/Allow from .*/Allow from 192.168.1.3
que claramente é um comando s
não finalizado e, portanto, relatado por sed
como tal.
Agora, a solução que você encontrou, usando echo
, funciona porque
echo $var
chama echo com dois argumentos (porque o espaço em branco não é citado, é interpretado como delimitador de argumentos), sendo o primeiro 192.168.1.3
e o segundo 192.168.1.4
; ambos são formulários que não são interpretados pela shell.
Agora, echo
apenas exibe seus argumentos (não-opcionais) separados por um espaço, portanto você agora obtém como linha de comando:
sed "25s/Allow from .*/Allow from 192.168.1.3 192.168.1.4/" -i test2
como pretendido.
Note, porém, que para a substituição de comandos, em vez de backticks, você deve usar $()
sempre que possível, pois é muito fácil errar os backticks. Portanto, o seguinte faz o que você quer:
sed "$A s/Allow from .*/Allow from $(echo $destStr)/" -i test2
Note que eu também aproveitei o fato de que sed
permite um espaço entre endereço e comando, para simplificar as citações. Em situações em que esse espaço extra não é possível, você também pode usar a seguinte sintaxe:
sed "${A}s/Allow from .*/Allow from $(echo $destStr)/" -i test2
Observe também que isso se baseia no fato de que os caracteres não espaciais em destStr
não são interpretados nem pelo shell, nem pelo sed
se ocorrer na string de substituição.