Impossibile indentare l'ereditarietà per abbinare il rientro del annidamento


62

Se ci fosse un "Primo problema mondiale" per gli script, questo sarebbe.

Ho uno dei seguenti codici in uno script che sto aggiornando:

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

Lo script invia e-mail senza problemi, ma il comando mailx è nidificato in un'istruzione if, quindi mi sembra che rimangano due opzioni:

  1. Inserire EOIuna nuova riga e interrompere i modelli di rientro o
  2. Continua con il rientro ma usa qualcosa come un'istruzione echo per ottenere mailx per succhiare la mia email.

Sono aperto alle alternative all'ereditarietà, ma se c'è un modo per aggirare questo è la mia sintassi preferita.

Risposte:


113

È possibile modificare l'operatore here-doc in <<-. È quindi possibile rientrare sia il here-doc che il delimitatore con le schede:

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

Si noti che è necessario utilizzare le schede , non gli spazi per rientrare nel documento qui. Ciò significa che l'esempio sopra non funzionerà copiato (Stack Exchange sostituisce le schede con spazi). Non ci possono essere virgolette attorno al primo EOFdelimitatore, altrimenti l'espansione dei parametri, la sostituzione dei comandi e l'espansione aritmetica non sono attive.


Bene, questo risolve il problema del rientro ma ora non sta espandendo la variabile che sto provando a inserire lì ( $dateLastChanged) se faccio la cosa hypen + virgolette nel tuo esempio, ma se prendo il trattino e citazioni e metto EOI su un nuova riga inizia a espandersi di nuovo.
Bratchley,

1
@JoelDavis: basta rimuovere le virgolette, mantenere il trattino.
Choroba,

5
Essere costretti a usare le schede è molto fastidioso. C'è un buon modo per aggirarlo?
con-f-use

2
@ con-f-use: puoi provare qualcosa di simile cat << EOF | sed 's/^ *//'e così via.
Choroba,

4
O ancora meglio: cat <<- EOF | awk 'NR==1 && match($0, /^ +/){n=RLENGTH} {print substr($0, n+1)}'. Questo rimuove la quantità di spazi precedenti nella prima riga da ogni riga del documento qui (grazie ad anubhava ).
con-f-use

5

Se non hai bisogno della sostituzione dei comandi e dell'espansione dei parametri all'interno del tuo documento qui, puoi evitare di usare le schede aggiungendo gli spazi iniziali al delimitatore:

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

Tuttavia, non sono riuscito a trovare un modo per utilizzare questo trucco e mantenere l'espansione dei parametri.


1
Per me, questa è l'unica risposta che risolve il problema del rientro senza usare spazi. shell-checktroverà eventuali rientri che non corrispondono agli spazi nella stringa tra virgolette. Utilizzare le virgolette doppie per l'espansione dei parametri?
Tom Hale,

4

Prova questo:

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

In questo caso non puoi avere righe con rientri diversi all'interno dell'ereditarietà. (Ciò importa se, ad esempio, il contenuto è uno script.)
ivan_pozdeev

2

Hmm ... Sembra che potresti sfruttare meglio l' --formatargomento qui da usare --printfinvece e passare il lotto su un tubo. Inoltre, il tuo if...fiè un comando composto: può richiedere un reindirizzamento che erediteranno tutti i comandi contenuti, quindi forse non è necessario nidificare l'eredità.

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

Sì, la mia revisione precedente diceva che non mi importava la sed/ awkparte. Parte della mia revisione oggi è stata quella di eliminarla poiché non era pertinente alla domanda. Ad ogni modo sono le sei e mezza e mezza dell'altra.
Bratchley,

@Bratchley - accidenti. L'ultima frase mi distrarrà per il resto della giornata.
Mikeserv,

In che modo vuoi dire?
Bratchley,

1
@Bratchley - Sembra un indovinello.
Mikeserv,

Ha. Non sono sicuro del paese di provenienza, ma questa è una frase comune negli Stati Uniti. Significa semplicemente "Approccio diverso allo stesso fine". Tuttavia, la tua soluzione aggira l'eredità.
Bratchley,

0

L'altro metodo sarebbe herestrings:

    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"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.