在写脚本处理文件系统时,经常需要加载很多模块。其中好多有用函数分散在各种不同的模块中。它们有些是Perl的内置函数,有些是在同Perl一起发行的标准模块中,另外一些是通过CPAN安装的。

下面来看15个最常用的工具。

当前路径

我经常需要知道当前所在的文件夹是什么。Cwd 模块有一个同名但是小写的函数 cwd,它会返回当前工作目录。

  1. use strict;
  2. use warnings;
  3. use Cwd qw(cwd);
  4. print cwd, "\n";

临时文件夹

我经常需要创建一批临时文件,并且确保它们在脚本结束的时候会被自动删除。要满足这个需求,最简单的方法是以 CLEANUP 选项使用 File::Temp 模块的 tempdir 函数来创建一个临时文件夹。

  1. use strict;
  2. use warnings;
  3. use autodie;
  4. use File::Temp qw(tempdir);
  5. my $dir = tempdir( CLEANUP => 1 );
  6. print "$dir\n";
  7. open my $fh, '>', "$dir/some_file.txt";
  8. print $fh "text";
  9. close $fh;

与操作系统无关的路径

如果上面的代码要在 Linux 和 Windows 上都要运行,人们会习惯在 Windows 平台上用反斜线分割路径。否则,在VMS上不能执行。而这就是 File::Spec::Functions模块中catfile函数的用武之地。

  1. use strict;
  2. use warnings;
  3. use File::Spec::Functions qw(catfile);
  4. use File::Temp qw(tempdir);
  5. my $dir = tempdir( CLEANUP => 1 );
  6. print "$dir\n";
  7. print catfile($dir, 'some_file.txt'), "\n";

执行这个代码后,能看到临时文件夹被打印出来,紧跟其后的是文件名字。

切换目录

通常情况下,先切换工作目录到临时文件夹再进行操作会更简单。但是也存在其他情况的写测试。此时我们可以使用内置函数chdir。

  1. use strict;
  2. use warnings;
  3. use autodie;
  4. use File::Temp qw(tempdir);
  5. use Cwd;
  6. my $dir = tempdir( CLEANUP => 1 );
  7. print cwd, "\n";
  8. chdir $dir;
  9. print cwd, "\n";
  10. open my $fh, '>', 'temp.txt';
  11. print $fh, 'text';
  12. close $fh;

以上看起来可以正常工作,但是当File::Temp尝试删除文件夹,而我们仍然“在里面”(之前切换工作目录到它)时就会有问题。

例如,我会得到下面的错误信息:

cannot remove path when cwd is /tmp/P3DZP_rmqg for /tmp/P3DZP_rmqg:

为了避免这种情况,我通常会在切换目录之前保存cwd的返回值,并且在最后再次调用chdir。

  1. my $original = cwd;
  2. ...
  3. chdir $original;

这样仍然会有个小问题。如果我在脚本中间调用exit(),或者在执行到chdir $original之前抛出异常而终止脚本,会发生什么?

Perl提供了一个解决方案:把最后一个chdir包裹在END块中。如此,就会确保无论何时、以何种方式退出脚本,这些代码都会执行到。

  1. my $original = cwd;
  2. ...
  3. END {
  4. chdir $original;
  5. }

相对路径

当写一个多文件构成的项目(例如一个或多个脚本,多个模块,也可能是多个模板),并且我不想“安装”它们时,最好的目录组织方式是:确保每个文件都在一个固定的相对位置。

所以,我的项目目录通常会包含一个脚本子文件夹,一个模块文件夹(lib), 一个模板文件夹, 等等:

project/
scripts/
lib/
templates/

那么,如何才能确保脚本能够找到模板? 我有好几个处理办法:

  1. use strict;
  2. use warnings;
  3. use autodie;
  4. use FindBin qw($Bin);
  5. use File::Basename qw(dirname);
  6. use File::Spec::Functions qw(catdir);
  7. print $Bin, "\n"; # /home/foobar/Rocket-Launcher/scripts
  8. print dirname($Bin), "\n"; # /home/foobar/Rocket-Launcher
  9. print catdir(dirname($Bin), 'templates'), "\n"; # /home/foobar/Rocket-Launcher/templates

FindBin模块导出的参量$bin存放着当前脚本的目录路径。 在我们的例子中就是指向project/scripts/文件夹的路径。

File::Basename中的dirname函数会传入一个路径,并返回除最后一部分之外的路径。

最后一行File::Spec::Functions模块的catdir函数基本上和我们之前看到的catfile一样。

除了打印到屏幕上,当然也可以使用catdir的返回值来表示templates路径。

从相对路径中加载模块

大部分情况下,要查找和加载的模块都会在项目的lib/文件夹中。为此,我们会把之前的代码和lib指令连用。这样会改变@INC变量的值,把相对路径添加在数组开头。

  1. use strict;
  2. use warnings;
  3. use autodie;
  4. use FindBin qw($Bin);
  5. use File::Basename qw(dirname);
  6. use File::Spec::Functions qw(catdir);
  7. use lib catdir(dirname($Bin), 'lib');
  8. use Rocket::Launcher;

假定存在lib/Rocket/Launcher.pm文件。

Perl5中19个最重要的文件系统工具的更多相关文章

  1. 10、Perl5中19个最重要的文件系统工具

    转载:http://www.cnblogs.com/nkwy2012/p/6027157.html 在写脚本处理文件系统时,经常需要加载很多模块.其中好多有用函数分散在各种不同的模块中.它们有些是Pe ...

  2. perl5 第十二章 Perl5中的引用/指针

    第十二章 Perl5中的引用/指针 by flamephoenix 一.引用简介二.使用引用三.使用反斜线(\)操作符四.引用和数组五.多维数组六.子程序的引用  子程序模板七.数组与子程序八.文件句 ...

  3. 安全运维中基线检查的自动化之ansible工具巧用

    i春秋作家:yanzm 原文来自:安全运维中基线检查的自动化之ansible工具巧用 前几周斗哥分享了基线检查获取数据的脚本,但是在面对上百台的服务器,每台服务器上都跑一遍脚本那工作量可想而知,而且都 ...

  4. ICC中对Skew进行Debug的好工具--Interactive CTS Window

    本文转自:自己的微信公众号<集成电路设计及EDA教程> ​以后打算交替着推送多种EDA工具的教程而不只是单纯针对某个工具,依次来满足不同粉丝的需求. 这里分享一篇多年之前写的推文,虽然时间 ...

  5. ubuntu12.04管理文件系统工具

    ubuntu12.04管理文件系统工具 以前可以自动管理系统盘和移动硬盘,刚重新安装了UBUNTU12.04LTS之后不行了,原来是这个工具: "PCMANFM" 群星_-_偏偏喜 ...

  6. CMMI-4中19个PA的大致描述

    组织过程资产库下面有组织级标准过程库, 这个库里一共有19各PA(就是标准过程啦) PA的英文是Process Area       CM(配置管理过程,英文是Configuration Manage ...

  7. perl5中锚位修饰符\A \z \Z 和perl4中^(开头)和$(结尾)的区别

    习惯使用perl4的开发者总是用^表示字符串开头锚位,用$表示字符串结尾锚位,比如\^https://\ 将会匹配所有以https://开头的字符串,同样,\.bmp$\将会匹配所有以.bmp结尾的字 ...

  8. Mac中的格式转换如何用读写工具Tuxera NTFS完成

    Tuxera NTFS for Mac是一款专门为Mac用户提供的NTFS驱动软件,它不仅可以进行磁盘文件的访问.编辑.传输和存储,还可以对硬盘进行维修检查以及修复. 今天小编就给大家简单介绍一下Tu ...

  9. eclipse中如何安装插件ADT及SDK工具

    1.如何在eclipse中安装ADT 首先下载ADT Plugin 下载地址: http://tools.android-studio.org/index.php/adt-bundle-plugin ...

随机推荐

  1. 【python cookbook】【数据结构与算法】2 从任意长度的可迭代对象中分解元素

    从某个可迭代对象中分解出N个元素,但是可迭代对象的长度可能超过N,会出现“分解值过多”的异常: 使用“*表达式”来解决该问题: Python 3.4.3 (v3.4.3:9b73f1c3e601, F ...

  2. KindEditor图片批量上传

    KindEditor编辑器图片批量上传采用了上传插件swfupload.swf,所以后台上传文件方法返回格式应为JSONObject的String格式(注). JSONObject格式: JSONOb ...

  3. 在Linux中打印函数调用堆栈【原创】

    本人学习笔记,代码参考如下网址 参考http://www.cnblogs.com/dma1982/archive/2012/02/08/2342215.html zhangbh@prolin-srv: ...

  4. Hosting custom WPF calendar control in AX 2012

    原作者: https://community.dynamics.com/ax/b/axilicious/archive/2013/05/20/hosting-custom-wpf-calendar-c ...

  5. Getting Started with the C# Driver

    1.下载 如果下载的.zip文件,只需要解压即可. 如果安装的.msi文件,它会将C#驱动DLL放在C:\Program Files (x86)\MongoDB\CSharp Driver xxx的位 ...

  6. 修改tomcat的logo

    每页的<head> 里添加   <link rel="icon" href="favicon.gif" />   图片名称必须是favi ...

  7. HDU 4715:Difference Between Primes

    Difference Between Primes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  8. nodejs 与数据库的连接

    //创建连接(封装) var mysql = require("mysql") function name(){ var con = mysql.createConnection( ...

  9. CentOS 6.5升级Python2.7

    1.下载并解压Python2.7的源码. . 2.编译与安装Python2.7. ./configure --prefix=/usr/local make && make altins ...

  10. html的<marquee></marquee>标签实现滚动效果

    页面的自动滚动效果,可由javascript来实现,但是今天无意中发现了一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 使用m ...