从 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。

相关内容