
我使用 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
。也許是一個perl
或awk
事物。
你甚至可以做一些事情
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:腳本的改進:
為什麼要使用 vim(以及硬拷貝
a2ps
)像和 之類的工具什麼時候enscript
存在?兩者都有各種有用的選項用於格式化文字和後記輸出。
while read line...
當您可以僅使用cat ${1:--} > "$infile"
將標準輸入儲存到檔案時,為什麼循環很慢?使用變數時,請始終用雙引號引起來。例如,不要使用
$infile
,"$infile"
而是使用 。使用 $(...) 而不是反引號。
該腳本不使用任何 bash 特定的功能,因此請使用
#!/bin/sh
(或#!/bin/dash
如果您安裝了它)。如果您使用的是
mkdir -p
,則無需測試該目錄是否已存在。mkdir -p
已經為你做到了。gjots2lpr
來自喬茨2包似乎完成了腳本所做的大部分或全部工作。您的腳本可以替換為一個簡單的包裝器,
gjots2lpr
該包裝器設定它用來覆蓋預設值的環境變數(例如告訴它是否使用a2ps
orenscript
、使用什麼 ps/pdf 檢視器、使用什麼列印命令等)。從
gjots2lpr -h
:
用法: gjots2lpr [-pt ] [ 檔案名稱 ... ]
列印文字檔案 - 如果可能,請使用 postscript 或 PDF 以及可用的預覽器和印表機對話方塊。它查找並使用它可以在系統上找到的任何實用程式。
如果未給予“檔案名稱”,則列印 STDIN。