{
my $sourcename = encode_filename("$dest/$file");
my $destname = encode_filename("$encdest/$file");
my $dirname= dirname("$encdest/$file");
mkpath($dirname);
system(sprintf('cat "%s" |openssl enc -des3 ' .
'-pass file:/var/lib/passphrase -a >"%s"',
$sourcename,$destname));
$counter;
}
}
my $delcounter = 0;
foreach my $file (@delfiles)
{
unlink("$encdest/$file");
$delcounter;
}
print STDERR "Finished (changed: $counter, deleted: $delcounter)n";
unlink("/tmp/$$.rsynclog");
sub encode_filename
{
my ($filename) = @_;
$filename =~ s/ / /g;
$filename =~ s/'/'/g;
$filename =~ s/"/"/g;
$filename =~ s/(/(/g;
$filename =~ s/)/)/g;
$filename =~ s/&/&/g;
$filename =~ s/#/#/g;
return($filename);
}
这个脚本非常简单,很容易使用 。在运行脚本时,指定源目录、参照文件的目标目录和文件加密版本的目标目录:$ rsyncrypt source destination destination.enc 。
脚本的第一部分在源和目标目录之间执行基本的同步以判断修改(见清单 5) 。这个操作生成记录修改的文件(在 /tmp 目录中) 。
清单 5. 在源和目标目录之间执行基本的同步
system("rsync --delete --recursive --times -og --links --perms " .
"--hard-links --itemize-changes $source $dest " .
">/tmp/$$.rsynclog 2>&1");
接下来,解析修改的列表,生成已经修改和删除的文件的列表(见清单 6) 。
清单 6. 解析修改的列表
while()
{
next if (m/sending incremental file list/);
chomp;
last if (length($_) == 0);
my ($changes,$filename) = split;
push @changedfiles,$filename if ($changes =~ m/^>f/);
push @delfiles,$filename if ($changes =~ m/^*del/);
}
对于每个修改过的文件,读取参照版本并在加密目标目录中创建加密版本(见清单 7) 。
清单 7. 创建每个修改过的文件的加密版本
foreach my $file (@changedfiles)
{
if (-f "$dest/$file")
{
my $sourcename = encode_filename("$dest/$file");
my $destname = encode_filename("$encdest/$file");
my $dirname= dirname("$encdest/$file");
mkpath($dirname);
system(sprintf('cat "%s" |openssl enc -des3 ' .
'-pass file:/var/lib/passphrase -a >"%s"',
$sourcename,$destname));
$counter;
}
}
因为要使用 shell 执行实际的加密,文件名必须进行编码 。需要对一些特殊字符进行转义,否则 shell 会解释它们 。
对于实际的加密,使用 openssl 和一个简单的文本文件(在 /var/lib/passphrase 中),这个文件包含信息编码所用的密码 。还可以创建或使用专门生成的密钥来执行此操作或希望使用的其他加密命令 。
最后,因为源目录中可能有已经删除的文件,还要把删除的文件从加密目录内容中删除(见清单 8) 。
清单 8. 把删除的文件从加密目录内容中删除
foreach my $file (@delfiles)
{
unlink("$encdest/$file");
$delcounter;
}
这个脚本非常有效,惟一的缺点是它需要信息的两个拷贝(参照目录和加密版本),而不只是一个 。另外,为了简化这个过程,并没有把权限、所有者和时间戳信息同步到加密版本,但是很容易添加这个特性 。因为这个脚本使用 rsync 生成修改的列表,这会显著减少需要加密的文件数量,可以使用相同的优化算法把新的文件加密版本同步到远程主机,从而只传输在上一次同步操作之后修改过的加密文件 。
结束语
本文讨论了几种不同的文件同步方法 。基本的 cp 命令并不是真正的同步命令,但是可以用来执行直接复制 。对于真正的同步操作,cp 命令花费的时间太长,效率很低 。在使用 tar 时,可以指定一个时间参照点,只复制在这个时间点之后修改过的文件 。但是,如果修改不明显或无法通过简单的比较查明,这个特性的意义也不大 。
推荐阅读
- /dev/tty文件在Unix操作系统中的妙用
- 有关UNIX启动的一些体会
- NetWare与UNIX的互联方法与实现
- Unix系统下Find命令的三个高级应用
- unix中利用Find命令备份根文件系统
- 手机照片怎么传到电脑文件夹里
- Unix系统中LVM硬盘管理的好帮手
- Unix文件安全检查利器- Tripwire
- 手机自动同步有什么用
- 深度解析Unix中inode块与超级块