web-dev-qa-db-fra.com

Impossible de mettre en retrait l'hérédoc pour correspondre au retrait de l'imbrication

S'il y a un "First World Problems" pour les scripts, ce serait celui-là.

J'ai le code suivant dans un script que je mets à jour:

if [ $diffLines -eq 1 ]; then
        dateLastChanged=$(stat --format '%y' /.bbdata | awk '{print $1" "$2}' | sed 's/\.[0-9]*//g')

        mailx -r "Systems and Operations <sysadmin@[redacted].edu>" -s "Warning Stale BB Data" jadavis6@[redacted].edu <<EOI
        Last Change: $dateLastChanged

        This is an automated warning of stale data for the UNC-G Blackboard Snapshot process.
EOI

else
        echo "$diffLines have changed"
fi

Le script envoie des e-mails sans problème, mais la commande mailx est imbriquée dans une instruction if, il me semble donc qu'il me reste deux choix:

  1. Mettez EOI sur une nouvelle ligne et cassez les modèles d'indentation ou
  2. Continuez avec l'indentation mais utilisez quelque chose comme une déclaration d'écho pour que mailx suce mon courrier électronique.

Je suis ouvert à des alternatives à heredoc, mais s'il existe un moyen de contourner ce problème, c'est ma syntaxe préférée.

66
Bratchley

Vous pouvez changer l'opérateur here-doc en <<-. Vous pouvez alors mettre en retrait à la fois le document ici et le délimiteur avec des onglets:

#! /bin/bash
cat <<-EOF
    indented
    EOF
echo Done

Notez que vous devez utiliser des tabulations, pas des espaces pour mettre en retrait le here-doc. Cela signifie que l'exemple ci-dessus ne fonctionnera pas copié (Stack Exchange remplace les tabulations par des espaces). Il ne peut pas y avoir de guillemets autour du premier délimiteur EOF, sinon l'expansion des paramètres, la substitution de commandes et l'expansion arithmétique ne sont pas en vigueur.

124
choroba

Si vous n'avez pas besoin de substitution de commande et d'extension de paramètres dans votre document ici, vous pouvez éviter d'utiliser des tabulations en ajoutant les espaces de tête au délimiteur:

$     cat << '    EOF'
>         indented
>     EOF
        indented
$     cat << '    EOF' | sed -r 's/^ {8}//'
>         unindented
>     EOF
unindented

Cependant, je ne pouvais pas trouver un moyen d'utiliser cette astuce et de conserver l'expansion des paramètres.

6
itsadok

Essaye ça:

sed 's/^ *//' >> ~/Desktop/text.txt << EOF
    Load time-out reached and nothing to resume.
    $(date +%T) - Transmission-daemon exiting.
EOF
5
robz

Hmm ... On dirait que vous pourriez mieux profiter du --format argument ici pour utiliser --printf à la place et passez le tout sur un tuyau. Aussi votre if...fi est une commande composée - elle peut prendre une redirection dont toutes les commandes contenues hériteront, donc vous n'avez peut-être pas du tout besoin d'imbriquer l'hérédoc.

if      [ "$diffLines" = 1 ]
then    stat --printf "Last Change: %.19y\n\n$(cat)\n" /.bbdata |
        mailx   -r  "Systems and Operations <sysadmin@[redacted].edu>" \
                -s  "Warning Stale BB Data" 'jadavis6@[redacted].edu'
else    echo    "$diffLines have changed"
fi      <<\STALE
This is an automated warning of stale data for the UNC-G Blackboard Snapshot process.
STALE
2
mikeserv

L'autre méthode serait l'héritage:

    mail_content="Last Change: $dateLastChanged

    This is an automated warning of stale data for the UNC-G Blackboard Snapshot process."
    mailx -r "Systems and Operations <sysadmin@[redacted].edu>" -s "Warning Stale BB Data" jadavis6@[redacted].edu <<<"$mail_content"
0
muru