如何在此处文档中包含具有变量扩展的代码

如何在此处文档中包含具有变量扩展的代码

尝试在文件中查找以下内容:

cat <<EOF > /etc/somefile.name
disks=($(lsblk | grep disk | cut -d " " -f 1 | grep -v │))

for i in "${!disks[@]}"; do
  echo 1024 > /sys/block/${disks[$i]}/queue/nr_requests
  echo 1024 > /sys/block/${disks[$i]}/queue/read_ahead_kb
  blockdev --setra 8192 /dev/${disks[$i]}
done
EOF

完成后,${!disks[@]}${disks[$i]}会转换为空白值:

for i in ""; do
  echo 1024 > /sys/block//queue/nr_requests
  echo 1024 > /sys/block//queue/read_ahead_kb
  blockdev --setra 8192 /dev/
done

如何预防呢?

答案1

您需要引用您选择作为此处文档标签的单词,以防止其内容被扩展:例如,<<'EOF'而不是<<EOF

引用手册:

这里文档的格式是:

[n]<<[-]word
       here-document
delimiter

[...]如果任何部分单词被引用,则分隔符是删除引号的结果单词,并且此处文档中的行未展开。如果单词未加引号,此处文档的所有行都会进行参数扩展、命令替换和算术扩展,\newline忽略字符序列,并且\必须使用 ' ' 来引用字符 ' \'、' $' 和 ' `'。

由于EOF(from cat <<EOF) 在代码中未加引号,因此此处文档中的所有扩展都会在cat运行时执行。然而,此时,此处文档本身并不是被处决,因此不会对disks进行任何分配,而是disks将其扩展为处理此处文档之前的值:

$ unset disks
$ disks=foo
$ cat <<EOF
> disks=bar
> echo "$disks"
> EOF
disks=bar
echo "foo"

相关内容