E-Mail-Nachrichten aus Mutt drucken – wie vermeidet man Zeilenumbrüche?

E-Mail-Nachrichten aus Mutt drucken – wie vermeidet man Zeilenumbrüche?

Ich verwende Mutt als E-Mail-Client und habe vor Kurzem beschlossen, meine E-Mail-Drucker-Einstellungen zu reparieren.

Ich kenne Muttprint, habe mich aber dazu entschieden, es nicht zu verwenden. Mir ist Folgendes eingefallen.

Am .muttrchabe ich:

set print_command="grep -v X-Spam-Status | $HOME/bin/mutt_print.sh"

Das ~/bin/mutt_print.shSkript, das ich aus Material, das ich im Internet gefunden habe, angepasst habe, sieht folgendermaßen aus:

#!/bin/bash

PDIR="$HOME/tmp/mutt_print" 
OPEN_PDF=zathura

# create temp dir if it does not exist
if [ ! -d "$PDIR" ]; then
    mkdir -p "$PDIR" 2>/dev/null
    if [ $? -ne 0 ]; then
        echo "Unable to make directory '$PDIR'" 1>&2
        exit 2
    fi
fi

infile="`mktemp $PDIR/mutt_XXXXXXXX.txt`"
tmpfile="`mktemp $PDIR/mutt_XXXXXXXX.ps`"
outfile="`mktemp $PDIR/mutt_XXXXXXXX.pdf`"

echo "infile = $infile"
echo "tmpfile = $tmpfile"
echo "outfile = $outfile"

while read line
do
  echo "$line" >> $infile
done < "${1:-/dev/stdin}"

echo "running vim $infile -c \"hardcopy > $outfile | q\""
vim $infile -c "hardcopy > $tmpfile | q"
echo "running ps2pdf $tmpfile $outfile"
ps2pdf $tmpfile $outfile

read
$OPEN_PDF $outfile >/dev/null 2>&1 &
sleep 1
rm $infile $tmpfile $outfile

Wenn ich also eine Nachricht drucken möchte, öffnet Mutt sie mit Zathura und ich kann sie entweder drucken oder als PDF speichern – das ist die Konfiguration, die ich möchte.

Mir ist jedoch aufgefallen, dass grepdas Entfernen der X-Spam-StatusZeile, obwohl ich es früher verwendet habe, nicht immer funktioniert: Manchmal scheint das Like unterbrochen zu sein, bevor es an den Druckbefehl gesendet wird, und ein Teil davon wird im PDF angezeigt:

Date: Wed, 11 May 2016 21:17:14 −0300
From: John Doe <[email protected]>
To: my-email@here
Subject: Re: blah
tests=FREEMAIL_FROM,HTML_MESSAGE,RDNS_NONE,T_DKIM_INVALID

Die X-Spam-StatusZeile in der Originalnachricht war

X-Spam-Status: No, hits=2.4 required=8.0 tests=FREEMAIL_FROM,HTML_MESSAGE,RDNS_NONE,T_DKIM_INVALID

welches zwischen required=8.0und unterbrochen ist tests....

Also – wie kann ich das Brechen dieser Zeile vermeiden?

(Ich freue mich auch über alle Verbesserungsvorschläge zum Skript)

Antwort1

Es hört sich an, als wäre diese X-Spam-StatusZeile ein „fortgesetzter“ RFC822-Header, der sich über mehrere Zeilen erstreckt.

Ein Header beginnt mit einem Nicht-Leerzeichen im ersten Zeichen einer Zeile. Eine nicht leere Zeile mit Leerzeichen am Anfang ist eine Fortsetzung der vorherigen Zeile, und eine leere Zeile beendet den Header.

Wenn Sie einen bestimmten Header herausfiltern möchten, benötigen Sie etwas, das RFC822 besser unterstützt als grep. Vielleicht ein perloder awketwas.

Vielleicht können Sie sogar etwas dagegen tun, indem Sie

while read line
do
  echo "$line" >> $infile
done < "${1:-/dev/stdin}"

z. B. keine Zeile wiedergeben, die mit „a“ beginnt X-Spam-Status(und ein Flag setzen), dann „fortgesetzte“ Zeilen überspringen, bis Sie auf eine neue Kopfzeile stoßen (und das Flag löschen).

In jedem Fall ist es erforderlich, dass das Programm weiß, wie RFC822-Header formatiert sind.

Vielleicht sollten Sie sich fragen, ob Ihnen die Überschrift in Ihrem Ausdruck wirklich so wichtig ist

Trotzdem ist ein Filter nicht so schwer

#!/user/bin/perl

my $skip=0;

# First do the headers
while(<STDIN>)
{
        #Test for end of headers
        if(/^\s*$/)
        {
                #copy the header ending blank
                printf $_;

                #exit the while loop
                last;
        }

        #Starts with non whitespace, new header
        $skip = 0 if /^\S/;

        #skip stuff if its the header we don't want
        $skip = 1 if /^X-Spam-Status/i;

        #copy lines if we're not skipping
        print $_ if !$skip;
}

# now the rest of the file
while(<STDIN>)
{
        #copy lines
        print $_;
}

Antwort2

Wie @infixed sagt, wird der X-Spam-Status-Header über mehrere Zeilen fortgesetzt.

Wenn Sie es installiert haben , können Sie das Dienstprogramm zum Verketten fortlaufender Header procmailverwenden .formail

Aus man formail:

-c Verkettet fortlaufende Felder im Header. Dies kann bei der Nachbearbeitung von E-Mails mit standardmäßigen (zeilenorientierten) Textdienstprogrammen praktisch sein.

Zum Beispiel:

set print_command="formail -c | grep -v X-Spam-Status: | $HOME/bin/mutt_print.sh"

Noch besser: Sie können formail -Ieinen Header entfernen, ohne dass Folgendes erforderlich ist grep -v:

set print_command="formail -I X-Spam-Status | $HOME/bin/mutt_print.sh"

-I Kopfzeilenfeld

Dasselbe wie -i, außer dass alle vorhandenen ähnlichen Felder einfach entfernt werden. Wenn das Headerfeld nur aus einem Feldnamen besteht, wird das Feld effektiv gelöscht.


AW: Verbesserungen am Skript:

  1. Warum vim verwenden (undHardcopy), wenn Tools wie a2psund enscriptexistieren?

    Beide verfügen über zahlreiche nützliche Optionen zur Textformatierung und Postscript-Ausgabe.

  2. Warum die langsame while read line...Schleife, wenn Sie einfach cat ${1:--} > "$infile"stdin in einer Datei speichern könnten?

  3. Setzen Sie Ihre Variablen bei Verwendung immer in Anführungszeichen. Verwenden Sie beispielsweise nicht $infile, sondern "$infile"stattdessen.

  4. Verwenden Sie $(...) anstelle von Backticks.

  5. Das Skript verwendet keine Bash-spezifischen Funktionen, verwenden Sie also #!/bin/sh(oder vielleicht #!/bin/dash, wenn Sie es installiert haben).

  6. Wenn Sie verwenden mkdir -p, müssen Sie nicht testen, ob das Verzeichnis bereits existiert. mkdir -perledigt das bereits für Sie.

  7. gjots2lprvon demgjots2Das Paket scheint das meiste oder alles von dem zu tun, was Ihr Skript tut.

    Ihr Skript könnte durch einen einfachen Wrapper ersetzt werden, gjots2lprder die Umgebungsvariablen festlegt, mit denen die Standardeinstellungen überschrieben werden (z. B. um anzugeben, ob a2psoder verwendet werden soll enscript, welcher PS/PDF-Viewer verwendet werden soll, welcher Druckbefehl verwendet werden soll usw.).

    Aus gjots2lpr -h:

Verwendung: gjots2lpr [-pt ] [ Dateiname ... ]

Druckt eine Textdatei - wenn möglich mit Postscript oder PDF und verfügbaren Vorschauprogrammen und Druckerdialogen. Es sucht und verwendet alle Dienstprogramme, die es auf dem System finden kann.

Wenn „Dateiname“ nicht angegeben ist, wird STDIN gedruckt.

verwandte Informationen