Re: Archivation through mutt?
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?
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?)
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?
--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?
--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--