Comment inclure du code avec des extensions de variables dans un here-doc

Oct 27 2020

Essayer de chat dans le fichier ceci:

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

Une fois cela fait, le ${!disks[@]}et ${disks[$i]}convertit en valeurs vides:

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

Comment éviter cela?

Réponses

3 fra-san Oct 27 2020 at 01:41

Vous devez citer le mot que vous avez choisi comme étiquette pour votre document ici pour éviter que son contenu ne soit développé: par exemple <<'EOF'au lieu de <<EOF.

Citant le manuel :

Le format des documents ici est:

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

[...] Si une partie du mot est citée, le délimiteur est le résultat de la suppression de la citation sur le mot , et les lignes dans le document ici ne sont pas développées. Si le mot n'est pas entre guillemets, toutes les lignes du document ici sont soumises à l'expansion des paramètres, à la substitution de commandes et à l'expansion arithmétique, la séquence de caractères \newlineest ignorée et « \» doit être utilisé pour citer les caractères « \», « $» et « `» .

Puisque EOF(from cat <<EOF) n'est pas entre guillemets dans votre code, toutes les extensions du document here-document sont effectuées lors de l' catexécution. À ce stade, cependant, le document ici lui-même n'est pas exécuté , par conséquent aucune affectation à disksn'est effectuée et disksest étendu à la valeur qu'il avait avant le traitement du document ici:

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