Citar o token de fim de linha faz isso. Cite em sua primeira linha:
cat > run1.sh <<-"EOF"
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?
Citar o token de fim de linha faz isso. Cite em sua primeira linha:
cat > run1.sh <<-"EOF"
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 "\\
. A barra invertida precisa ser escapada como script1.sh
"script2.sh
, o que transforma a string em <<END_SCRIPT2
.
O script acima escreve <<-END_SCRIPT2
como
Executando estas saídas
%pre% ... e script1.sh
são criados:
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%