
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 .muttrc
habe ich:
set print_command="grep -v X-Spam-Status | $HOME/bin/mutt_print.sh"
Das ~/bin/mutt_print.sh
Skript, 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 grep
das Entfernen der X-Spam-Status
Zeile, 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-Status
Zeile 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.0
und 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-Status
Zeile 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 perl
oder awk
etwas.
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 procmail
verwenden .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 -I
einen 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:
Warum vim verwenden (undHardcopy), wenn Tools wie
a2ps
undenscript
existieren?Beide verfügen über zahlreiche nützliche Optionen zur Textformatierung und Postscript-Ausgabe.
Warum die langsame
while read line...
Schleife, wenn Sie einfachcat ${1:--} > "$infile"
stdin in einer Datei speichern könnten?Setzen Sie Ihre Variablen bei Verwendung immer in Anführungszeichen. Verwenden Sie beispielsweise nicht
$infile
, sondern"$infile"
stattdessen.Verwenden Sie $(...) anstelle von Backticks.
Das Skript verwendet keine Bash-spezifischen Funktionen, verwenden Sie also
#!/bin/sh
(oder vielleicht#!/bin/dash
, wenn Sie es installiert haben).Wenn Sie verwenden
mkdir -p
, müssen Sie nicht testen, ob das Verzeichnis bereits existiert.mkdir -p
erledigt das bereits für Sie.gjots2lpr
von 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,
gjots2lpr
der die Umgebungsvariablen festlegt, mit denen die Standardeinstellungen überschrieben werden (z. B. um anzugeben, oba2ps
oder verwendet werden sollenscript
, 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.