尝试在文件中查找以下内容:
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"