Se encapsularmos a string inicial em ' s em vez de " s, a $q não será imediatamente expandida. Podemos então expandi-lo mais tarde usando eval :
#!/bin/sh
q='#!/bin/sh\nq=$q;eval "echo \"\$q\""';eval "echo \"$q\""
Infelizmente, o \n não é expandido, os ' s e " s são perdidos e o \" s passa a " s.
Saída:
#!/bin/sh\nq=#!/bin/sh\nq=$q;eval "echo \"\$q\"";eval echo "$q"
Estamos bem perto, mas tentar consertar o escape com sed acaba se tornando um tanto complicado.
O link de jw013 recomenda uma abordagem bastante compreensível:
- Parte 1: defina alguns dados (por exemplo, uma variável) que contenha a segunda parte do programa
- Parte 2: Use os dados para gerar a primeira parte do programa e, em seguida, use os dados para gerar a segunda parte do programa. (Lidar com o envolvimento e o escape necessário para a parte 1 aqui.)
Aqui está uma tentativa grosseira inicial de que:
#!/bin/sh
data="echo -e \"#!/bin/sh\ndata=\"\$data\"\"\n\$data"
echo -e "#!/bin/sh\ndata=\"$data\"\n$data"
Saída:
#!/bin/sh
data="echo -e "#!/bin/sh
data="$data""
$data"
echo -e "#!/bin/sh
data="$data""
$data
Essa tentativa sofre o \n ser sempre interpretado e o \ s sendo perdido. Precisamos de alguma maneira de escapar da string de dados quando a imprimirmos novamente.
Aqui está uma melhoria que usa várias chamadas para echo para evitar os problemas com \n s.
#!/bin/sh
data='echo "#!/bin/sh"\necho "data=$data"\necho -e "$data"'
echo "#!/bin/sh"
echo "data='$data'"
echo -e "$data"
Ela sofre de uma pequena falha que é difícil de superar, perdendo ' s na saída (o meio echo ):
#!/bin/sh
data='echo "#!/bin/sh"\necho "data=$data"\necho -e "$data"'
echo "#!/bin/sh"
echo "data=$data"
echo -e "$data"
Isso é tudo que tenho para você. Alguns pontos de partida com problemas de escape. Boa sorte!