Mark M. Hoffman on 9 Sep 2004 00:57:03 -0000

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] Using fetchmail to read from an Exchange public folder for learning spam

Hi Mike:

> On Wed, Sep 08, 2004 at 11:52:46AM -0400, Mike Leone said:
> > /usr/bin/fetchmail -a -s -n -p IMAP --folder 'INBOX.Learn Spam' -m 'bash -c
> > "/usr/bin/tee >(/usr/bin/sa-learn --spam --single \ 
> >                  > /dev/null)|/usr/bin/spamc|/usr/lib/cyrus-imapd/deliver
> > $LOGNAME"'

* Stephen Gran <> [2004-09-08 19:38:09 -0400]:
> So it does this:
> Runs fetchmail, and fetches all (-a) mail in (-s) silent mode (no running
> ouput).  It uses norewrite (-n), to keep the headers intact, so that
> SA gets them as is.  Then it spawns a subshell as a delivery agent with
> the -m option.  The subshell uses tee to cat to stdout everything coming
> from fetchmail, and tee's output goes to sa-learn.  He is then delivering
> the mail to his cyrus account, although you won't want to do that.

Right... here's a little more detail about that:

Tee copies stdin to stdout and to one or more files which are specified
on the command line.  E.g.
        $ cat file1 | tee file2
The contents of file1 go to the screen, and get copied to file2.
A common real-world usage is something like this:
        $ make 2>&1 | tee build.log
I.e. capture all stdout and stderr to the file build.log, but still throw
it onto the screen so I can watch.
>> /usr/bin/fetchmail -a -s -n -p IMAP --folder 'INBOX.Learn Spam' -m 'bash -c
>> "/usr/bin/tee >(/usr/bin/sa-learn --spam --single \
>>                  > /dev/null)|/usr/bin/spamc|/usr/lib/cyrus-imapd/deliver
I'll break the part in double quotes like this: tee $x $y
First, $x is this: >(/usr/bin/sa-learn --spam --single > /dev/null)
Within bash, the form ">(command)" is called a process substitution.
Bash is going to create a FIFO.  Whatever is written to that FIFO will
be passed to sa-learn.  The *name* of that FIFO will be substituted into
the command line of tee by bash.  Result: stdin is passed to sa-learn.
Next, $y is this: | /usr/bin/spamc | /usr/lib/cyrus-imapd/deliver $LOGNAME
So, that's just a simple pipe, where stdout is passed to that chain.  But
remember, tee passes stdin directly to stdout as well, so...
The net result is: stdin is forked into two copies, one is passed to sa-learn,
the other is passed to the pipeline ending with deliver.
>> And I would want:
>> /usr/bin/fetchmail -a -s -n -p IMAP --folder '???????' -m 'bash -c
>> "/usr/bin/tee >(/usr/bin/sa-learn --spam --single > /dev/null)"'
>> exchange-server
Since you removed the deliver pipeline, you don't need the tee to make a
copy of stdin anymore... just pass it straight to sa-learn:
        'bash -c "/usr/bin/sa-learn --spam --single > /dev/null"'

I hope that helps.                                                                                                                                                      

Mark M. Hoffman

Philadelphia Linux Users Group         --
Announcements -
General Discussion  --