Je veux imprimer le code dans un fichier en utilisant cat <<EOF >>
:
cat <<EOF >> brightup.sh
!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi
EOF
mais quand je vérifie la sortie du fichier, j'obtiens ceci:
!/bin/bash
curr=1634
if [ -lt 4477 ]; then
curr=406;
echo > /sys/class/backlight/intel_backlight/brightness;
fi
J'ai essayé de mettre des guillemets simples, mais la sortie comporte également les guillemets simples. Comment puis-je éviter ce problème?
Vous n'avez besoin que d'un changement minimal. citez le délimiteur here-document après <<
.
cat <<'EOF' >> brightup.sh
ou l'équivalent de backslash-escape:
cat <<\EOF >>brightup.sh
Sans citer, le document ici subira une substitution de variable, les backticks seront évalués, etc., comme vous l'avez découvert.
Si vous devez développer certaines valeurs, mais pas toutes, vous devez échapper individuellement à celles que vous souhaitez empêcher.
cat <<EOF >>brightup.sh
#!/bin/sh
# Created on $(date # : <<-- this will be evaluated before cat;)
echo "\$HOME will not be evaluated because it is backslash-escaped"
EOF
produira
#!/bin/sh
# Created on Fri Feb 16 11:00:18 UTC 2018
echo "$HOME will not be evaluated because it is backslash-escaped"
Comme suggéré par @ fedorqui , voici la section pertinente de man bash
:
Voici des documents
Ce type de redirection demande au shell de lire les entrées de la source actuelle jusqu’à ce qu’une ligne contenant uniquement un délimiteur (sans blancs à la fin) soit visible. Toutes les lignes lues jusqu'à ce point sont ensuite utilisées comme entrée standard pour une commande.
Le format de here-documents est:
<<[-]Word here-document delimiter
Aucun développement de paramètre, substitution de commande, développement arithmétique ou développement de chemin d'accès n'est effectué sur Word. Si des caractères sont cités dans Word, le délimiteur est le résultat de la suppression des guillemets dans Word et les lignes du document here ne sont pas développées. Si Word n'est pas entre guillemets, toutes les lignes du document here sont soumises à l'expansion des paramètres, à la substitution de commandes et à l'expansion arithmétique . Dans ce dernier cas, la séquence de caractères\est ignorée et doit être utilisée pour citer les caractères \, $ et `.
Ou bien, en utilisant vos marqueurs EOF, vous devez citer le marqueur initial pour que l'extension ne soit pas effectuée:
#-----v---v------
cat <<'EOF' >> brightup.sh
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi
EOF
IHTH
Cela devrait fonctionner, je viens de le tester et cela a fonctionné comme prévu: aucune expansion, substitution, ou quoi que vous ayez eu.
cat <<< '
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi' > file # use overwrite mode so that you don't keep on appending the same script to that file over and over again, unless that's what you want.
Utiliser ce qui suit fonctionne aussi.
cat <<< ' > file
... code ...'
En outre, il convient de noter que lorsqu’on utilise heredocs, tel que << EOF
, la substitution et l’extension de variable, etc., ont lieu. Donc, faire quelque chose comme ça:
cat << EOF > file
cd "$HOME"
echo "$PWD" # echo the current path
EOF
entraînera toujours le développement des variables $HOME
et $PWD
. Donc, si votre répertoire personnel est /home/foobar
et que le chemin actuel est /home/foobar/bin
, file
ressemblera à ceci:
cd "/home/foobar"
echo "/home/foobar/bin"
au lieu de l'attendu:
cd "$HOME"
echo "$PWD"