O problema era escape de shell . \
é um caractere especial no shell e também em grep
.
Em:
grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
export_cc\ =\ \$\{dir\}/aaa/bbb/ccc
foi interpretado pelo shell para uma string export_cc = ${dir}/aaa/bbb/ccc
antes de passar para grep
. Você pode usar o strace para verificar:
$ strace grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
execve("/bin/grep", ["grep", "export_cc = ${dir}/aaa/bbb/ccc",...
Com Substituição de comando :
grep 'printf %q 'export_cc = ${dir}/aaa/bbb/ccc'' file
Sem as aspas duplas, o resultado da substituição de comandos foi split e glob por o shell em três partes: export_cc\
, =\
e \$\{dir\}/aaa/bbb/ccc
. O shell tratou-os como três strings, escapando de todas as barras invertidas e passando-os para grep
como export_cc\
, =\
, \$\{dir\}/aaa/bbb/ccc
:
$ strace grep $(printf %q 'export_cc = ${dir}/aaa/bbb/ccc') file
execve("/bin/grep", ["grep", "export_cc\", "=\", "\$\{dir\}/aaa/bbb/ccc",...
grep
recebeu um padrão com uma barra invertida export_cc\
seguido por nada e mostrou a mensagem Trailing backslash
.
Para que funcione, você precisa substituir o comando por aspas duplas e usar printf com %s
em vez de %q
:
$ grep "$(printf %s 'export_cc = ${dir}/aaa/bbb/ccc')" file
export_cc = ${dir}/aaa/bbb/ccc