Evitando a expansão de parâmetros várias vezes

2

Eu tenho um código que está escrevendo um script que está escrevendo outro script:

    cat > step1.sh <<-EOF  
        *other commands*  
            cat > step2.sh <<-EOF4 
                if [ -f PM.log ]; then
                    awk '/testphrase/{ f=1;r=""; next }f && /testphrase2/{f=0}f{ r=(r=="")? $0: r RS $0 }END{ print r }' PM.log > tmp1.log
                    checkfree=($(cat tmp1.log))
                    wait 
                    sed -i '$ d' tmp${mold}.log
                    wait
                fi
        EOF4
        qsub step2.sh
EOF
qsub step1.sh

Estou tentando impedir a expansão de parâmetro com o "$ 0" na linha 5 do código, bem como com a linha 6 do código ($ (cat tmp1.log)). Estou ciente de que usar "\" antes do $ impediria a expansão do parâmetro uma vez:

\
    cat > step1.sh <<-EOF  
        *other commands*  
            cat > step2.sh <<-EOF4 
                if [ -f PM.log ]; then
                    awk '/testphrase/{ f=1;r=""; next }f && /testphrase2/{f=0}f{ r=(r=="")? $0: r RS $0 }END{ print r }' PM.log > tmp1.log
                    checkfree=($(cat tmp1.log))
                    wait 
                    sed -i '$ d' tmp${mold}.log
                    wait
                fi
        EOF4
        qsub step2.sh
EOF
qsub step1.sh

No entanto, como esse script é escrito por outro script, não sei como manipular para evitar expansões duplas e triplas à medida que cada script é gravado.

Eu também sei que você pode editar o token de fim de arquivo, mas há outros parâmetros (como moldes na linha 8) dentro do arquivo que eu quero expandir, então também não posso fazer isso.

Como posso impedir que esses termos particulares sejam expandidos sempre?

    
por A. B 09.10.2017 / 18:57

2 respostas

1

Citar o token de fim de linha faz isso. Cite em sua primeira linha:

cat > run1.sh <<-"EOF"
    
por 09.10.2017 / 19:06
0

Considere o seguinte exemplo de script (todas as indentações são guias literais):

#!/bin/sh

var='hello'

cat >script1.sh <<-END_SCRIPT1
        #!/bin/sh
        echo 'This is script1 ($var)'
        printf '\
#!/bin/sh
echo 'This is script2 (hello)'
printf '\
This is script1 (hello)
$0 is "script1.sh"
is "%s"\n' "\
#!/bin/sh
echo 'This is script2 (hello)'
printf '$0 is "%s"\n' "$0"
" END_SCRIPT2 printf '$0 is "%s"\n' "$0"
is "%s"\n' "\
awk '!f && /testphrase/  { f = 1; r = "" }
     f  && /testphrase2/ { f = 0 }
     f                   { r = (r == "" ? $0 : r RS $0) }
     END                 { print r }'
" cat >script2.sh <<END_SCRIPT2 #!/bin/sh echo 'This is script2 ($var)' printf '\\
#!/bin/sh

var='hello'

cat >script1.sh <<-END_SCRIPT1
        #!/bin/sh
        echo 'This is script1 ($var)'
        printf '\
#!/bin/sh
echo 'This is script2 (hello)'
printf '\
This is script1 (hello)
$0 is "script1.sh"
is "%s"\n' "\
#!/bin/sh
echo 'This is script2 (hello)'
printf '$0 is "%s"\n' "$0"
" END_SCRIPT2 printf '$0 is "%s"\n' "$0"
is "%s"\n' "\
awk '!f && /testphrase/  { f = 1; r = "" }
     f  && /testphrase2/ { f = 0 }
     f                   { r = (r == "" ? $0 : r RS $0) }
     END                 { print r }'
" cat >script2.sh <<END_SCRIPT2 #!/bin/sh echo 'This is script2 ($var)' printf '\\%pre% is "%s"\n' "\\%pre%" END_SCRIPT2 END_SCRIPT1
is "%s"\n' "\\%pre%" END_SCRIPT2 END_SCRIPT1

No documento aqui-externo, precisamos escapar do $ em "$0" as "\"\\"" para não expandi-lo pelo script que está escrevendo o documento.

Para poder escrever o documento interno aqui, precisamos garantir que o documento aqui-externo esteja escrevendo "\\script1.sh" . A barra invertida precisa ser escapada como script2.sh , o que transforma a string em <<END_SCRIPT2 .

O script acima escreve <<-END_SCRIPT2 como

%pre%

Executando estas saídas

%pre%

... e script1.sh são criados:

%pre%

Observe que o documento interno aqui é criado usando wait , não awk . Quaisquer guias principais serão comidas quando o documento aqui-externo for criado (como é evidente quando se olha para f && /testphrase2/ ).

Como um aparte, você não precisa das duas chamadas para /testphrase/ em seu código, já que não parece executar nenhum processo em segundo plano.

Seu código next também está com defeito, pois a condição /testphrase/ nunca seria verdadeira. Se /testphrase2/ corresponder, então %code% será executado, forçando o código a continuar com a próxima linha de entrada. Se %code% não corresponder, então %code% não corresponderá a nenhum deles.

Você pode tentar isso:

%pre%     
por 06.05.2018 / 00:02