Eu uso o mutt como cliente de e-mail e recentemente decidi consertar minha configuração de impressão de e-mail.
Eu conheço o Muttprint, mas decidi não usá-lo. Eu descobri o seguinte.
Em .muttrc
, eu tenho:
set print_command="grep -v X-Spam-Status | $HOME/bin/mutt_print.sh"
O ~/bin/mutt_print.sh
script, que adaptei de coisas que encontrei na net, é este:
#!/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
Então, quando decido imprimir uma mensagem, Mutt a abre com o Zathura e posso imprimi-la ou salvar o PDF - esta é a configuração que desejo.
Porém, percebi que embora eu grep
removesse a X-Spam-Status
linha, nem sempre funciona: às vezes o like parece quebrado antes de ser enviado para o comando de impressão, e parte dele é exibido no 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
A X-Spam-Status
linha da mensagem original era
X-Spam-Status: No, hits=2.4 required=8.0 tests=FREEMAIL_FROM,HTML_MESSAGE,RDNS_NONE,T_DKIM_INVALID
que está quebrado entre required=8.0
e tests...
.
Então - como posso evitar a quebra dessa linha?
(Também aceito sugestões de melhorias no roteiro)
Responder1
Parece que essa X-Spam-Status
linha é um cabeçalho RFC822 'continuado' que abrange várias linhas.
Um cabeçalho começa com espaços não em branco no primeiro caractere de uma linha. Uma linha não em branco com espaço em branco no início é uma continuação da linha anterior e uma linha em branco termina os cabeçalhos.
Se você deseja filtrar um cabeçalho específico, precisará de algo mais compatível com RFC822 do que grep
. Talvez uma coisa perl
ou awk
outra.
Você pode até fazer algo sobre isso
while read line
do
echo "$line" >> $infile
done < "${1:-/dev/stdin}"
como não fazer eco de uma linha que começa com a X-Spam-Status
(e definir um sinalizador) e, em seguida, pular as linhas 'continuadas' até atingir um novo cabeçalho (e limpar o sinalizador).
De qualquer forma, é necessário que o programa conheça como os cabeçalhos RFC822 são formatados.
Talvez você precise se perguntar se você realmente se importa tanto com aquele cabeçalho em sua impressão
Ainda assim, um filtro não é tão difícil
#!/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 $_;
}
Responder2
Como diz @infixed, o cabeçalho X-Spam-Status continua em várias linhas.
Se você tiver procmail
instalado, poderá usar seu formail
utilitário para concatenar cabeçalhos continuados.
De man formail
:
-c Concatena campos continuados no cabeçalho. Pode ser conveniente ao pós-processar mensagens com utilitários de texto padrão (orientados a linhas).
Por exemplo:
set print_command="formail -c | grep -v X-Spam-Status: | $HOME/bin/mutt_print.sh"
Melhor ainda, você pode usar formail -I
para remover um cabeçalho, sem a necessidade de grep -v
:
set print_command="formail -I X-Spam-Status | $HOME/bin/mutt_print.sh"
-I campo de cabeçalho
O mesmo que -i, exceto que quaisquer campos semelhantes existentes são simplesmente removidos. Se headerfield consistir apenas em um nome de campo, ele efetivamente excluirá o campo.
RE: melhorias no script:
Por que usar o vim (ecópia impressa) quando as ferramentas gostam
a2ps
eenscript
existem?Ambos têm todos os tipos de opções úteis para formatar texto e saída postscript.
Por que o loop lento
while read line...
quando você poderia usar apenascat ${1:--} > "$infile"
para salvar o stdin em um arquivo?Sempre coloque aspas duplas em suas variáveis ao usá-las. por exemplo, não use
$infile
, use"$infile"
em vez disso.Use $(...) em vez de crases.
O script não usa nenhum recurso específico do bash, então use
#!/bin/sh
(ou talvez#!/bin/dash
se você o tiver instalado).Se estiver usando
mkdir -p
, não será necessário testar se o diretório já existe.mkdir -p
já faz isso por você.gjots2lpr
degjots2package parece fazer a maior parte ou tudo o que o seu script faz.Seu script pode ser substituído por um wrapper simples
gjots2lpr
que define as variáveis de ambiente usadas para substituir os padrões (por exemplo, para informar se deve usara2ps
orenscript
, qual visualizador ps/pdf usar, qual comando de impressão usar, etc.).De
gjots2lpr -h
:
Uso: gjots2lpr [-pt ] [ nome do arquivo ... ]
Imprime um arquivo de texto - se possível usando postscript ou PDF e pré-visualizadores e caixas de diálogo da impressora disponíveis. Ele procura e usa todos os utilitários que encontrar no sistema.
Se 'nome do arquivo' não for fornecido, STDIN será impresso.