Печать сообщений электронной почты от mutt – как избежать разрыва строки?

Я использую mutt в качестве почтового клиента и недавно решил исправить мою настройку электронной почты.

Я знаю о Muttprint, но я решил не использовать его. Я придумал следующее.

На .muttrc меня есть:

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

Сценарий ~/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 , это не всегда срабатывает: иногда подобное кажется сломанным до того, как оно будет отправлено команде print, а часть ее отображается в PDF-файле :

 Date: Wed, 11 May 2016 21:17:14 −0300 From: John Doe <john.doe@somewhereoutthere.com> 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...

Итак – как я могу избежать нарушения этой линии?

(Я также приветствую любые предложения по улучшению сценария)

2 Solutions collect form web for “Печать сообщений электронной почты от mutt – как избежать разрыва строки?”

Похоже, что строка X-Spam-Status является «продолженным» заголовком RFC822, который охватывает несколько строк.

Заголовок начинается с не-пробелов в первом символе строки. Непустая строка с пробелом в начале является продолжением предыдущей строки, а пустая строка заканчивает заголовки.

Если вы хотите отфильтровать определенный заголовок, вам понадобится нечто большее, чем RFC822, чем grep . Возможно, perl или awk .

Вы могли бы даже что-то сделать в этом

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

например, не эхо-строку, начинающуюся с 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 $_; } в #!/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 $_; } в #!/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 $_; } 

Поскольку @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, за исключением того, что любые существующие аналогичные поля просто удаляются. Если заголовочное поле состоит только из имени поля, оно эффективно удаляет это поле.


RE: улучшение скрипта:

  1. Зачем использовать vim (и hardcopy ), если существуют такие инструменты, как a2ps и enscript ?

    У обоих из них есть всевозможные полезные опции для форматирования текста и вывода postscript.

  2. Почему медленное while read line... когда вы можете просто использовать cat ${1:--} > "$infile" чтобы сохранить stdin в файл?

  3. Всегда используйте двойные кавычки вокруг своих переменных при их использовании. например, не используйте $infile , вместо этого используйте "$infile" .

  4. Используйте $ (…) вместо обратных тиков.

  5. Сценарий не использует никаких специфичных для bash функций, поэтому используйте #!/bin/sh (или, может быть, #!/bin/dash если вы его установили).

  6. Если вы используете mkdir -p , вам не нужно проверять, существует ли каталог. mkdir -p делает это для вас уже.

  7. gjots2lpr из пакета gjots2 , похоже, делает больше всего или всего, что делает ваш скрипт.

    Ваш скрипт можно заменить простой оберткой вокруг gjots2lpr которая устанавливает переменные среды, которые он использует, чтобы переопределить значения по умолчанию (например, чтобы сказать, использовать ли a2ps или enscript , какой просмотрщик ps / pdf использовать, какую команду печати использовать и т. Д.) ,

    Из gjots2lpr -h :

Использование: gjots2lpr [-pt] [имя_файла …]

Распечатывает текстовый файл – если возможно, используя постскриптум или PDF, а также доступные предварительные просмотры и диалоговое окно принтера. Он ищет и использует любые утилиты, которые он может найти в системе.

Если «filename» не задано, печатается STDIN.

  • Не удается отправить почту через sendmail
  • heirloom-mailx отправляет электронные письма дополнительным получателям
  • Unix-команда «mail», отправьте почту в адрес .onion address
  • Как переадресовать локальную * nix-почту на внешнюю учетную запись, сохраняя локальную копию?
  • Как работает почтовая команда?
  • Этого достаточно для рабочего почтового сервера?
  • Разница между адресом «Reply-to» и «От адреса в электронном письме»
  • Как я могу заплатить с mailx?
  • Linux и Unix - лучшая ОС в мире.