我想生成一个稍后可以调用的bash文件,就像这样
cat <<-SCRIPT >test-$$
#!/bin/bash
osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release)
if [ "$osType" = ...]
then
...
fi
exit
SCRIPT
当我调试时,grep 命令总是以正确的方式执行,为什么?也尝试使用 awk 相同的错误
但如果我这样做
cat <<-SCRIPT >test-$$
#!/bin/bash
rpm -q somepackage > test-$$
rm test-$$-lock
exit
SCRIPT
我没有看到 rpm 命令以正确的方式执行? test-$$ 和 test-$$-lock 也会有相同的 $$ 吗?
答案1
类似here-doc的<<-SCRIPT
行为就像双引号字符串,因为扩展是在其中处理的。为了防止这种情况,请引用分隔符:
$ cat <<EOF
1+1 = $((1+1))
EOF
1+1 = 2
与
$ cat <<'EOF'
1+1 = $((1+1))
EOF
1+1 = $((1+1))
所以在这里:
cat <<-SCRIPT >test-$$
...
osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release)
该grep
命令位于命令替换中,由于SCRIPT
未加引号而被处理,因此在使用此处文档时会执行该命令。
另一方面,这里:
cat <<-SCRIPT >test-$$
#!/bin/bash
rpm -q somepackage > test-$$
rm test-$$-lock
exit
SCRIPT
没有命令替换,因此没有命令运行。该rpm -q somepackage
部分只是文本。但是,如果使用不带引号的分隔符,则$$
此处文档内部将立即扩展为输出文件名称中使用的相同值。也就是说,如果当前 shell 的 PID 是 1234,则该cat
命令将创建test-1234
包含行rpm -q somepackage > test-1234
.
使用带引号的分隔符,$$
将保持原样,结果将被称为test-1234
包含rpm -q somepackage > test-$$
.如果您现在test-1234
作为脚本运行,那么$$
将会扩展,并且那将使用 shell 的 PID。它可能与创建文件时使用的值不同。
无论如何,$$
inrpm .. > test-$$
和rm test-$$-lock
都会扩展到相同的值。