我有一个正在编写一个脚本的代码,该脚本正在编写另一个脚本:
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
我试图使用代码第 5 行中的“$0”以及代码第 6 行 ($(cat tmp1.log)) 来防止参数扩展。我知道在 $ 之前使用“\”会阻止参数扩展一次:
\$0
但是,因为这个脚本是由另一个脚本编写的,所以我不知道如何在编写每个脚本时进行操作以防止双重和三重扩展。
我还知道您可以编辑文件结尾标记,但我确实想扩展文件中的其他参数(例如第 8 行中的 Mold),所以我也无法这样做。
我怎样才能阻止这些特定术语每次都被扩展?
答案1
引用行尾标记可以做到这一点。在第一行引用它:
cat > run1.sh <<-"EOF"
答案2
考虑以下示例脚本(所有缩进都是文字制表符):
#!/bin/sh
var='hello'
cat >script1.sh <<-END_SCRIPT1
#!/bin/sh
echo 'This is script1 ($var)'
printf '\$0 is "%s"\n' "\$0"
cat >script2.sh <<END_SCRIPT2
#!/bin/sh
echo 'This is script2 ($var)'
printf '\\\$0 is "%s"\n' "\\\$0"
END_SCRIPT2
END_SCRIPT1
在外部的here-document中,我们需要转义in,$
以免"$0"
编写"\$0"
文档的脚本扩展它。
为了能够编写内部here-document,我们需要确保外部here-document正在写入"\$0"
。反斜杠需要转义为\\
,这会将字符串变成"\\\$0"
。
上面的脚本写script1.sh
为
#!/bin/sh
echo 'This is script2 (hello)'
printf '\$0 is "%s"\n' "\$0"
END_SCRIPT2
printf '$0 is "%s"\n' "$0"
运行此输出
This is script1 (hello)
$0 is "script1.sh"
...并script2.sh
创建:
#!/bin/sh
echo 'This is script2 (hello)'
printf '$0 is "%s"\n' "$0"
请注意,内部的here-document是使用<<END_SCRIPT2
而不是创建的<<-END_SCRIPT2
。当创建外部此处文档时,任何前导选项卡都将被耗尽(在查看 时很明显script1.sh
)。
顺便说一句,您不需要wait
在代码中进行两次调用,因为您似乎没有运行任何后台进程。
您的awk
代码也是错误的,因为f && /testphrase2/
条件永远不会成立。如果/testphrase/
匹配,则next
执行 then,强制代码继续下一行输入。如果/testphrase/
不匹配,则/testphrase2/
也不会匹配。
你可以尝试这个:
awk '!f && /testphrase/ { f = 1; r = "" }
f && /testphrase2/ { f = 0 }
f { r = (r == "" ? $0 : r RS $0) }
END { print r }'