1

我有以下 bash 脚本来更新 maildir 文件的 mtimes:

#!/bin/bash

for i in /test/emailfile

do
    date=$(sed -n '/Received: from/ { :a; n; /;/ {s/.*; //p;q}; b a }' "$i")
    newdate=$(date -d "$date" +'%Y%m%d%H%M.%S')
    touch -t "$newdate" "$i"
done

该脚本一直运行良好,具有如下标准标头:

Delivery-date: Sun, 22 Apr 2007 00:15:13 -0600
Received: from an-out-0708.google.com ([209.85.132.243])
    by x.xxxx.com with esmtp (Exim 4.63)
    (envelope-from <xxxxxx@gmail.com>)
    id 1HfVLs-0002Io-RQ
    for x@xxxxx.com; Sun, 22 Apr 2007 00:15:13 -0600

交货日期为 2007 年。如果我触摸该文件以使文件日期从今天开始,然后运行我的脚本,则文件日期将恢复为接收日期。

但是,当尝试在具有以下标题的电子邮件上运行我的脚本时:

Delivery-date: Mon, 15 Dec 2008 17:26:37 -0800
Received: from xxxxxx ([130.194.13.165])
    by xxxxxxx with esmtp (Exim 4.69)
    (envelope-from <xxxxxi@xxxxx.xxx.xx>)
    id 1LCOhp-0006fm-2g
    for xxxxx@xxxxxx.com; Mon, 15 Dec 2008 17:26:37 -0800

日期显然没有恢复。我看不出标题以任何方式明显不同。我需要重置 mtimes,因为许多邮件客户端使用文件时间显示为收到的时间。我的脚本已经处理了超过 3000 封电子邮件,确保所有客户端在移动服务器和所有具有相同日期的文件后以正确的顺序显示电子邮件,但由于某种原因,它不适用于特定的电子邮件。我是否在脚本中留下了一些明显的东西?

编辑:日期显然是从脚本中恢复的,但是无论脚本将日期设置为什么,依赖 mtimes 的客户端都不会显示此消息。权限相同,布局和文件名格式也相同。以下是来自 ls -la 的帖子

-rw-rw----   1 username username    11769 Dec 14 21:25 1229318728.H329820P11297.xxxxx.serverxxxxx.com:2,S
-rw-rw----   1 username username     3366 Dec 15 17:26 1229390797.H476913P25671.xxxxx.serverxxxxx.com:2,S
-rw-rw----   1 username username     1149 Dec 22 05:39 1229953142.H901034P11016.xxxxx.serverxxxxx.com:2,S
-rw-rw----   1 username username     7557 Dec 23 15:43 1230075791.H700954P8392.xxxxx.serverxxxxx.com:2,S

无法正确显示的文件是倒数第二个。有什么方法可以调试为什么会发生这种情况?

4

3 回答 3

1

它似乎对我来说很好用,试试这个小曲子,看看你会得到什么。

#!/bin/bash
echo 'Delivery-date: Sun, 22 Apr 2007 00:15:13 -0600
Received: from an-out-0708.google.com ([209.85.132.243])
    by x.xxxx.com with esmtp (Exim 4.63)
    (envelope-from <xxxxxx@gmail.com>)
    id 1HfVLs-0002Io-RQ
    for x@xxxxx.com; Sun, 22 Apr 2007 00:15:13 -0600' | sed -n '/Received: from/ { :a; n; /;/ {s/.*; //p;q}; b a }'
date -d "Sun, 22 Apr 2007 00:15:13 -0600" +'%Y%m%d%H%M.%S'
echo 'Delivery-date: Mon, 15 Dec 2008 17:26:37 -0800
Received: from xxxxxx ([130.194.13.165])
    by xxxxxxx with esmtp (Exim 4.69)
    (envelope-from <xxxxxi@xxxxx.xxx.xx>)
    id 1LCOhp-0006fm-2g
    for xxxxx@xxxxxx.com; Mon, 15 Dec 2008 17:26:37 -0800' | sed -n '/Received: from/ { :a; n; /;/ {s/.*; //p;q}; b a }'
date -d "Mon, 15 Dec 2008 17:26:37 -0800" +'%Y%m%d%H%M.%S'

我得到(如预期的那样):

Sun, 22 Apr 2007 00:15:13 -0600
200704221415.13
Mon, 15 Dec 2008 17:26:37 -0800
200812161026.37

所以我不确定为什么你的不起作用,尽管该脚本的输出应该是一个很好的起点。

您可以做的另一件事是临时修改您的脚本,如下所示:

: : : : :
echo touch -t "$newdate" "$i"
touch -t "$newdate" "$i"
: : : : :

这将输出您正在尝试的实际命令。

还要检查目录和单个文件的文件权限。

“ls -l”(mtime)和“ls -lc”(ctime)在实际的可疑邮件文件中为您提供了什么?可能是您的脚本运行良好,但用户电子邮件客户端未使用 mtime/ctime。

编辑后:

引用“但是无论脚本将日期设置为什么,依赖 mtime 的客户端都不会显示此消息”,我的回答是客户端依赖 mtime。

用Sherlock自己的话说,一旦你排除了所有其他可能性,剩下的无论多么不可能,都必须如此。我注意到一件事:您是否只是说消息根本没有显示(或者我认为我们正在谈论的日期错误)?

如果是后者,您需要查看邮件客户端以查看其实际获取日期的位置。只是出于兴趣,客户认为它是什么日期(它是否与标题中的任何日期匹配?

如果是前者,那是我们可以讨论的另一个问题。

我认为这是您需要从这里开始的(客户端),由于我的专业知识更多是脚本而不是电子邮件客户端,因此我可能无法提供进一步的帮助。不过,我很想看看结果如何,所以我会喜欢这个问题。

于 2009-01-22T11:47:13.497 回答
1

以下脚本使用日期而不是邮件消息的接收日期属性。这将日期设置为与某些邮件应用程序使用的日期相匹配,并且还简化了 sed 语句。它还包括在遇到错误/无效日期时改进的错误处理。

#!/bin/bash
echo "Process folder : $@"
for i in $( ls -1 $@ )
do
#    date=$(sed -n '/Received: from/ { :a; n; /;/ {s/.*; //p;q}; b a }' "$i") 
#    date=$(sed -n -f ~/scripts/fix.sed "$i")
    date=$(sed  -n '/^Date: / {s/^Date: //p;q}' "$i")
    newdate=$(date -d "$date" +'%Y%m%d%H%M.%S')
    returnCode=$?
    if [ "$returnCode" != "0" ]
    then
      echo "Date Return Code : $returnCode"
      echo "Message file : $i received at : $date"
    fi
touch -c -t "$newdate" "$i"
done
于 2011-02-24T19:34:17.660 回答
0

你确定 - 它对我有用。

我所做的唯一更改是:

#!/bin/bash

for i in "$@"

do
    date=$(sed -n '/Received: from/ { :a; n; /;/ {s/.*; //p;q}; b a }' "$i")
    newdate=$(date -d "$date" +'%Y%m%d%H%M.%S')
    touch -c -t "$newdate" "$i"
done

touch -c这样文件就不会通过触摸创建。

for i in "$@"以便它在命令行参数而不是固定文件上运行。

$ touch data2 ; ls -l data2
-rw-r--r-- 1 leeder leeder 250 2009-01-22 11:43 data2
$ bash test.sh data data2 ; ls -l data2
-rw-r--r-- 1 leeder leeder 250 2008-12-16 01:26 data2
于 2009-01-22T11:45:44.577 回答