從 mutt 列印電子郵件——如何避免換行?

從 mutt 列印電子郵件——如何避免換行?

我使用 mutt 作為電子郵件用戶端,最近決定修復我的電子郵件列印設定。

我了解 Muttprint,但我決定不使用它。我想出了以下內容。

在 上.muttrc,我有:

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

~/bin/mutt_print.sh我根據網路上找到的內容改編的腳本是這樣的:

#!/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

因此,當我決定列印一條訊息時,Mutt 用 Zathura 打開它,我可以列印它或保存 PDF——這就是我想要的設定。

但是,我注意到雖然我曾經grep刪除了該X-Spam-Status行,但它並不總是有效:有時類似的內容在發送到列印命令之前似乎已被破壞,並且其中的一部分顯示在PDF中:

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

X-Spam-Status原始訊息中的行是

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

required=8.0和之間被打破tests...

那麼──我該如何避免這條線被打破呢?

(我也歡迎對腳本提出任何改進建議)

答案1

聽起來該X-Spam-Status行是一個跨越多行的「連續」RFC822 標頭。

標題以行的第一個字元中的非空格開頭。開頭帶有空格的非空白行是前一行的延續,空白行結束標題。

如果您想過濾掉特定標頭,您將需要比 .RFC822 更了解的東西grep。也許是一個perlawk事物。

你甚至可以做一些事情

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

就像不回顯以 a 開頭的行X-Spam-Status(並設定一個標誌),然後跳過「連續」行,直到遇到新標題(並清除標誌)。

無論哪種方式,程式都需要了解 RFC822 標頭的格式。

也許您需要問自己是否真的如此關心列印輸出中的標題

不過,過濾器沒那麼難

#!/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 $_;
}

答案2

正如 @infixed 所說,X-Spam-Status 標頭連續多行。

如果您已procmail安裝,則可以使用其實formail用程式來連接連續的標頭。

man formail

-c 連接標頭中的連續欄位。使用標準(面向行)文字實用程式後處理郵件時可能會很方便。

例如:

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

更好的是,您可以使用formail -I刪除標頭,而不需要grep -v

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

-I 標頭字段

與 -i 相同,只是刪除任何現有的類似欄位。如果 headerfield 僅包含欄位名稱,則它會有效地刪除該欄位。


RE:腳本的改進:

  1. 為什麼要使用 vim(以及硬拷貝a2ps)像和 之類的工具什麼時候enscript存在?

    兩者都有各種有用的選項用於格式化文字和後記輸出。

  2. while read line...當您可以僅使用cat ${1:--} > "$infile"將標準輸入儲存到檔案時,為什麼循環很慢?

  3. 使用變數時,請始終用雙引號引起來。例如,不要使用$infile"$infile"而是使用 。

  4. 使用 $(...) 而不是反引號。

  5. 該腳本不使用任何 bash 特定的功能,因此請使用#!/bin/sh(或#!/bin/dash如果您安裝了它)。

  6. 如果您使用的是mkdir -p,則無需測試該目錄是否已存在。 mkdir -p已經為你做到了。

  7. gjots2lpr來自喬茨2包似乎完成了腳本所做的大部分或全部工作。

    您的腳本可以替換為一個簡單的包裝器,gjots2lpr該包裝器設定它用來覆蓋預設值的環境變數(例如告訴它是否使用a2psor enscript、使用什麼 ps/pdf 檢視器、使用什麼列印命令等)。

    gjots2lpr -h

用法: gjots2lpr [-pt ] [ 檔案名稱 ... ]

列印文字檔案 - 如果可能,請使用 postscript 或 PDF 以及可用的預覽器和印表機對話方塊。它查找並使用它可以在系統上找到的任何實用程式。

如果未給予“檔案名稱”,則列印 STDIN。

相關內容