Re: Archivation through mutt?

2001-09-25 Thread darren chamberlain

Matìj Cepl [EMAIL PROTECTED] said something to this effect on 09/25/2001:
 I have worked on archmail script a little bit yesterday and the 
 results are attached (I used zip to ensure verbatim transport). 
 I have divided script into two, because I was not able to debugg 
 your find command. However, I have now problem with bash. 
 Consider following screenshot:
 
 mail $ test -f ./sluzebni/; echo $?
 1
 mail $ test -d ./sluzebni/; echo $?
 0
 mail $ ll
 total 332
 -rw-rw-r--1 matejmatej   0 kvì  3 19:30 drafts
 drwxrwxr-x2 matejmatej4096 záø  9 15:54 list
 drwxrwxr-x2 matejmatej4096 záø 25 10:26 pratele
 -rw-rw-r--1 matejmatej  270658 kvì  2 06:03 sent-200104
 -rw-rw-r--1 matejmatej   45374 kvì  3 20:58 sent-200105
 drwxrwxr-x2 matejmatej4096 záø 25 10:48 sluzebni
 
 If understand my bash manpage well, the second command should 
 produce 1 too. Have you any idea why it doesn't? I am using bash 
 2.04.11(1)-release on RedHat GNU/Linux 7.0.

Why would the second produce 1?

Here is what I get, doing something similar:

bash$ echo $BASH_VERSION
2.03.8(1)-release
bash$ if test -d ./tmp/; then echo ./tmp is a directory; fi
./tmp is a directory
bash$ test -d ./tmp; echo $?
0

Remember, under *nix, 0 is true, 1 is false, so this is the
correct behavior.

-f tests that (quoting man test): FILE exists and is a regular
file, i.e., not a directory, thus the 1 (false) return value for
the first call to test.

If you are using shell builtins and standard commands, you can
rely on what you are used to as truth if you merely call test
in a boolean context:

  if test -d ./sluzebni/; then
# it is a directory; do your stuff
  else
# not a directory; perhaps check -f or -S?
  fi

The contents of $? is probably not what you're after, so much as
a true value, unless you are checking for a specific error message.

(darren)

-- 
Don't sweat the petty things, and don't pet the sweaty things.



Re: Archivation through mutt?

2001-09-25 Thread Mariusz Drozdziel

On wto, 25 wrz, in tucznik.ml.mutt-users, you wrote:

 mail $ test -f ./sluzebni/; echo $?
 1
 mail $ test -d ./sluzebni/; echo $?
 0


 If understand my bash manpage well, the second command should 
 produce 1 too. Have you any idea why it doesn't? I am using bash 

No, it shouldn't. :) When value '1' is returned, when test
was failed, so in the first example test command tells that
object ./sluzebni is not a file. In the second case value is 
zero becouse test was passwd. :)




Greets, Nova.
-- 
 
  Mariusz.
 
 
= Mariusz Drodziel [EMAIL PROTECTED] * 2:[EMAIL PROTECTED] ==



test command in shell (was Re: Archivation through mutt?)

2001-09-25 Thread Olaf Schulz

Hallo Matj, 
I did not read your script but I want to answer your shell question:

On Tue, Sep 25, 2001 at 11:15:32AM -0400, Matj Cepl wrote:
  [...mail archival script...]

 I have divided script into two, because I was not able to debugg 
 your find command. However, I have now problem with bash. 
 Consider following screenshot:
 
 mail $ test -f ./sluzebni/; echo $?
testing if an ordinary file ./sluzebni/ exists
 1
no.

 mail $ test -d ./sluzebni/; echo $?
testing if  ./sluzebni/ is a directory.
 0
yes.
 mail $ ll
 total 332
 -rw-rw-r--1 matejmatej   0 kv  3 19:30 drafts
 drwxrwxr-x2 matejmatej4096 z  9 15:54 list
 drwxrwxr-x2 matejmatej4096 z 25 10:26 pratele
 -rw-rw-r--1 matejmatej  270658 kv  2 06:03 sent-200104
 -rw-rw-r--1 matejmatej   45374 kv  3 20:58 sent-200105
 drwxrwxr-x2 matejmatej4096 z 25 10:48 sluzebni
 
 If understand my bash manpage well, the second command should 
 produce 1 too. Have you any idea why it doesn't? I am using bash 
 2.04.11(1)-release on RedHat GNU/Linux 7.0.

two things, very general in unix:
in the shell a return code 0 means "OK, no errors, true"
in opposite to most programming and scripting languages where
0 is associated with false and values different from 0 with true.

what test (a shell builtin for bash) does, I wrote above.
ask your shell: help test 
to get a full list of it's behaviour.


Olaf
extra for you switched my font to iso8859-2



Re: Archivation through mutt?

2001-09-07 Thread Piet Delport


--H1spWtNR+x+ondvy
Content-Type: multipart/mixed; boundary=y0ulUmNC+osPPQO6
Content-Disposition: inline


--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, 06 Sep 2001 at 23:43:41 -0400, Matej Cepl wrote:
 On 7 Sep 2001, at 2:21, Piet Delport wrote:
  - The ${foo} syntax expands to the contents of variable foo, not
to the output of command foo.  For command substitution, either
use $(foo), or `foo` (note the backticks).  The $(foo) form nests
easier than the `foo` form, but the latter is more common between
shells.
=20
 Thanks, I will use $().

It's mostly a matter of personal taste, i know, but i still think `` is
better, as (AFAIK) it predates $(), and should be supported by more
shells.  Not that i can name any examples though. :-)

[snip]
  I've attached my version of your script with all of the above worked
  in.  Warning: it's still totally untested.  Comments welcome.
=20
 Actually, you haven't.

Gah, my apologies.  This is the result of sending long mails in the wee
hours of the morning without proof-reading them.

 However, I have reconstructed the most of your advice and the result
 is attached. The find command you proposed wouldn't work, because the
 purpose of the command is to move messages from the folder in $MAILDIR
 to the one in $ARCHDIR, which cannot be accomplished via mere {}.

Indeed.  I was actually planning to tackle this problem with something
like basename, but completely forgot about it before pressing `send'.

 See my proposed solution, which is not optimal either, because it
 doesn't work with mailboxes in the subdirectories of $MAILDIR.  Any
 thoughts?

Looks promising, aside from a minor quoting problem (the argument for
mutt -e should be in double-quotes, as 1. single-quoted strings can't
contain single-quotes, not even escaped ones, and 2. no variable or
command substitution takes place at all in single-quoted strings,
meaning the final argument to mutt would be to save the messages in a
folder literally called $ARCHDIR/$(basename {}) (except that {} would
still replaced by find...)).

There's a biggish problem with this approach that i've overlooked until
now though:

The -exec argument of find passes everything directly to the program
that is its argument, with no shell or expansion performed whatsoever,
aside from replacing a literal '{}' anywhere with the found file's name.
So even after fixing the quotes, the basename {} bit will be
interpreted too early, and *find* will be passed the basename of {},
which stays {}.  So there's no net effect, mutt will still be
instructed to save the messages to {}.

I thought about this, and came up with a different approach, that (i
think :-) solves the above problem, along with correctly handling files
in sub-directories:

find $MAILDIR/ \
\! -name 'sent-*' \
\! -name trash \
\! -name draft \
-exec /bin/sh -c \
mutt -f '{}' -e \
\push 'tag-message~d -\`date --date=3D$ARCHDATE +%d/%m/%Y\`=0D\
tag-prefixsave-message\`echo '{}' | sed -e \s:^$MAILDIR:$ARCHDIR:\\`=
=0D\
quit'\ \;

(This is beginning to approach some the scariest shell scripting i've
written...)

Explanations (as much for my benefit as anyone else's):

- I'm listing each of the excluded folder names separately as \! -name
  foo;  this is to make it slightly easier to add/remove folder names.

- I'm -execing /bin/sh -c, instead of mutt directly, because a sub-shell
  is needed to interpret shell constructs *after* find has replaced {}
  with the mail folder name.

- The crucial bit here is:

`echo '{}' | sed -e s:^$MAILDIR:$ARCHDIR:`

  This will eventually get parsed to (say):

`echo '/my_mail_dir/subdir/myfolder' | sed -e s:^/my_mail_dir:/my_arch_di=
r:`

  which should result in /my_arch_dir/subdir/myfolder being passed to
  mutt as the folder to save the expired messages into.

 And I still do not know how to achieve the last command (archiving of
 the sent-* mailboxes).

This isn't going to be too easy, i think.  I'm playing around with some
ideas here though, will let you know what turns up.

[snip (Free)BSD date(1) using -v for relative dates, as opposed to GNU
date(1)'s -d and --date...]

This presents a portability problem...  either non-GNU systems will have
to install GNU date or the script should have an option to switch
between the two syntaxes, neither of which is particularly fun.  Maybe
an equivalent perl one-liner can be used instead of date(1), to sidestep
the problem?

--=20
Piet Delport [EMAIL PROTECTED]
Today's subliminal thought is:

--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=archmail.new

#!/bin/sh
# $Id: archmail,v 1.2 2001/09/05 14:26:09 user Exp $
#

##set variables and functions
# I prefer to have all configuration in one place (and therefore
# I do not use relative dates in mutt).
ARCHDATE=3 month ago
TRASHDATE=1 fortnight ago

Re: Archivation through mutt?

2001-09-06 Thread Piet Delport


--M9NhX3UHpAaciwkO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, 05 Sep 2001 at 14:39:40 -0400, Matej Cepl wrote:
[...mail archival script...]
=20
 However, I am really not a programmer and I am still slightly scare of
 Bash. Could you comment, please, on the attached script and tell me
 whether I am to shoot off my foot with this script?

Some quick comments:

- The ${foo} syntax expands to the contents of variable foo, not to
  the output of command foo.  For command substitution, either use
  $(foo), or `foo` (note the backticks).  The $(foo) form nests easier
  than the `foo` form, but the latter is more common between shells.

- In your -e strings for mutt, you must remember to insert the enter
  keypress after commands like tag-message, as mutt doesn't do it
  for you.  enter won't do though, you either need a \n or a
  literal carriage return (which can be gotten in vi by pressing ^V followed
  by ^M, for example).

- You also need to surround push's arguments with quotes of some kind,
  otherwise it complains about having too many arguments.

- Unless this is really what you intended, you probably want to add a
  quit to the end of each -e string, otherwise mutt will wait
  interactively for you to quit each time.

- ... and, a minor quibble, it's a good idea to use tag-prefix in
  place of ;, in case you ever decide to remap ;.

- For find, you should escape the parentheses to prevent the shell from
  interpreting them.  Also, it's safer to quote the
-name sent-*
  bit as
-name 'sent-*'
  just in case your current directory happens to contain a file starting
  with sent-.

Portability issues:

- Declare functions without the leading function, as the latter is a
  bash thing.

- For find, instead of -not, use !.  And, like the parens, it's best
  to escape this too.

Then, about the find statement in the script...

Currently, you have:

 find $MAILDIR/ \
  -not ( -name sent-* -o -name trash -o -name draft ) \
  -printf %P\n | xargs process

where process is a shell function that takes care of archiving all old
mail in the folder named by its first argument ($1).

The find statement will fail to work for two reasons:

1.  xargs foo takes its input and gives *all of them at once* as
arguments for foo.  So process would only ever affect the first
folder found, the rest would be ignored.
2.  xargs will never even find process in the first place, as it's a
shell function.  It can only see and call `real' programs.

To get around this, you can do something like the following (sorry for
the long line):

find $MAILDIR/ \
\! \( -name 'sent-*' -o -name trash -o -name draft \) \
-exec mutt -f {} \
  -e 'push tag-message~d -'`date --date=3D$ARCHDATE '+%d/%m/%Y'`=0D=
tag-prefixsave-message{}=0Dquit\ \;
   =20
Don't panic. :-) Basically, this does the find, and just directly
executes mutt on each of the matching folders.

I've attached my version of your script with all of the above worked in.
Warning: it's still totally untested.  Comments welcome.

[ One minor problem so far is that the FreeBSD date(1) doesn't
understand the --date option, but has a -v option rather, with:
-v -3m
meaning 3 months ago, and
-v +7d
meaning 7 days from now, etc.  Does GNU date(1) support the -v option? ]

--=20
Piet Delport [EMAIL PROTECTED]
Today's subliminal thought is:

--M9NhX3UHpAaciwkO
Content-Type: application/pgp-signature
Content-Disposition: inline

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE7mBMYzRUP82sZFCcRAktzAKClfCT7VwcBMjqTY8jprNK3xKoRgQCeOVIx
oBNzxtYl8c0Go51IZExr6rQ=
=5pLQ
-END PGP SIGNATURE-

--M9NhX3UHpAaciwkO--