So fügen Sie Code mit variablen Erweiterungen in ein Here-Doc ein
Der Versuch, in der Datei Folgendes zu erfassen:
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
Sobald dies erledigt ist, konvertiert das ${!disks[@]}und ${disks[$i]}in leere Werte:
for i in ""; do
echo 1024 > /sys/block//queue/nr_requests
echo 1024 > /sys/block//queue/read_ahead_kb
blockdev --setra 8192 /dev/
done
Wie kann man das verhindern?
Antworten
Sie müssen das Wort zitieren, das Sie als Bezeichnung für Ihr Here-Dokument gewählt haben, um zu verhindern, dass dessen Inhalt erweitert wird: z . B. <<'EOF'anstelle von <<EOF.
Zitat des Handbuchs :
Das Format der Here-Dokumente ist:
[n]<<[-]word here-document delimiter[...] Wenn ein Teil des Wortes in Anführungszeichen gesetzt wird, ist das Trennzeichen das Ergebnis der Entfernung von Anführungszeichen für das Wort , und die Zeilen im Dokument hier werden nicht erweitert. Wenn das Wort nicht in Anführungszeichen gesetzt ist, werden alle Zeilen des hier gezeigten Dokuments einer Parametererweiterung, einer Befehlssubstitution und einer arithmetischen Erweiterung unterzogen. Die Zeichenfolge
\newlinewird ignoriert und '\' muss verwendet werden, um die Zeichen '\', '$' und '`' in Anführungszeichen zu setzen. .
Da EOF(von cat <<EOF) in Ihrem Code nicht in Anführungszeichen steht, werden alle Erweiterungen im Here-Dokument ausgeführt, wenn sie catausgeführt werden. Zu diesem Zeitpunkt wird das Here-Dokument selbst jedoch nicht ausgeführt , daher erfolgt keine Zuordnung zu disksund es diskswird auf den Wert erweitert, den es vor der Verarbeitung des Here-Dokuments hatte:
$ unset disks
$ disks=foo $ cat <<EOF
> disks=bar
> echo "$disks"
> EOF
disks=bar
echo "foo"