我想避免设置 IMAP 服务器,而是使用 mailutilsmovemail
结合SSHFS
将一些邮件从外部主机移至本地计算机。不幸的是,它失败了:
$ sshfs -o noforget exthost:/ /mnt/sshfs
$ movemail /mnt/sshfs/var/mail/dirdi /home/user/dirdi/ext_mail
movemail: mailbox `/mnt/sshfs/var/mail/dirdi': cannot lock: Lock file check failed
但是,锁文件/var/mail/dirdi.lock
实际上是在 exthost 上创建的。我查看了源代码并追踪错误,直到这里:http://git.savannah.gnu.org/cgit/mailutils.git/tree/libmailutils/base/locker.c?h=release-3.5#n120在我看来,stat_check
函数内部的某些检查失败了,但我无法判断是哪一个以及为什么。
答案1
作为一种解决方法,我创建了一个在远程邮箱的本地副本上smovemail
运行的 shell 脚本:movemail
#!/bin/bash
# initialize variables
status=0
src=
dest=
remotefs=
copy=
mountpoint=
lockfile=
# function to print errors
function error {
echo "(E) ${1}" >&2
status=1
}
# function to tear down created environment
function tear_down {
# remove local copy of remote mailbox
if [[ "${copy}" ]]; then
rm -- "${copy}" ||
error "Unable to remove local copy of remote mailbox '${copy}.'"
fi
# remove lockfile
if [[ "${lockfile}" ]]; then
rm -- "${lockfile}" ||
error "Unable to remove lockfile '${lockfile}. Remote mailbox may still be locked.'"
fi
# unmount SSHFS
mount | cut -d " " -f 3 | grep "${mountpoint}" >/dev/null &&
fusermount -u "${mountpoint}" 2>/dev/null ||
error "Unable to unmount remote filesystem mounted at '${mountpoint}'"
# remove mountpoint
if [[ "${mountpoint}" ]]; then
rmdir "${mountpoint}" 2>/dev/null ||
error "Unable to remove mountpoint '${mountpoint}'"
fi
exit ${status}
}
# register tear down function to run in any case
trap tear_down EXIT
# print usage
if [[ ${#} -ne 2 ]]; then
error "Usage: $(basename ${0}) remote_mailbox local_mailbox"
exit
fi
# TODO implement better parameter sanitization
# create mountpoint
mountpoint=$(mktemp -d 2>/dev/null) || {
error "Unable to create mountpoint."
exit
}
# determine locations
src="${mountpoint}/"$(basename "${1}" 2>/dev/null)
remotefs=$(dirname "${1}" 2>/dev/null)
dest="${2}"
# mount SSHFS
sshfs "${remotefs}" "${mountpoint}" -o workaround=rename,reconnect,uid=$(id -u),gid=$(id -g) >/dev/null 2>&1 || {
error "Unable to mount remote filesystem '${remotefs}'"
exit
}
# lock remote mailbox
lockfile=$(mktemp -p "${mountpoint}" 2>/dev/null) || {
error "Unable to create lockfile"
exit
}
mv -n "${lockfile}" "${src}.lock"
if [[ -f "${lockfile}" ]]; then
error "Unable to lock mailbox."
exit
fi
lockfile="${src}.lock"
# create local copy
copy=$(mktemp 2>/dev/null) || {
error "Unable to create copy of remote mailbox."
exit
}
cp "${src}" "${copy}" 2>/dev/null || {
error "Unable to copy remote mailbox."
exit
}
# run movemail
movemail "${copy}" "${dest}" || {
error "Unable to move mails."
exit
}
# play back copy
cp "${copy}" "${src}" 2>/dev/null || {
error "Unable to play back local copy."
exit
}
可以通过以下方式调用$ smovemail remoteuser@remotehost:/var/mail/remoteuser /var/mail/localuser
如果您想使用此脚本,请随意使用,但是请注意:此脚本利用命令mv -n
来锁定远程邮箱,因此基于此命令的假设原子在 SSHFS 文件系统上。根据我的研究,这个假设并不总是成立!但是,我进行了一些测试,并没有让它崩溃,所以对我来说这已经足够好了。
非常欢迎对改进提出意见和建议。