免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1907 | 回复: 4
打印 上一主题 下一主题

熟悉perl 朋友帮忙指点一下这个脚本? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-10-17 00:21 |只看该作者 |倒序浏览
刚学习perl

这个代码:        printf "#d dd of=\$origin seek=%.0f if=\$cow iflag=direct skip=%.0f count=%u bs=%ub\n",
                $old, $new, $merge_count, $header->{chunk_size};
       
为什么只能运行打印出来,不执行运行呢
./dm /dev/sdb

\$origin  \$cow 不赋予变量真实的值

谢谢


完整代码如下:
  1. #!/usr/bin/perl
  2. use Fcntl qw(:DEFAULT O_DIRECT);

  3. use strict;
  4. use warnings;

  5. my $file = $ARGV[0] or die "usage: $0 <input device or file>\n";

  6. # max exception chunk size apears to be 512k
  7. # we need an aligned buffer for O_DIRECT.
  8. # dirty trick to get a PAGE_ALIGNed buffer in perl
  9. # be _very_ careful with $buf, do not touch it,
  10. # and do not assign to it, not even implicitly!
  11. my $bufsize = 512*1024;
  12. my $align = 4096;
  13. my $buf = "x" x ($bufsize + $align);
  14. my $offset = $align - (unpack "l", pack "p", $buf) % $align;

  15. my $header = { magic => 0, valid => 0, version => 0, chunk_size => 0, };

  16. sysopen(IN, $file, O_RDONLY | O_DIRECT) or die "sysopen($file, O_DIRECT): $!\n";

  17. sub read_header()
  18. {
  19.         my $c = sysread(IN, $buf, 512, $offset);
  20.         die "problem reading header, \$c: $c, \$!: $!"
  21.                  if ($c != 512);
  22.          <at> {$header}{qw(magic valid version chunk_size)} =
  23.                 unpack "A4VVV", substr($buf, $offset, 512);

  24.         die "does not appear to be a lvm-snapshot-cow device"
  25.                 if $header->{magic} ne 'SnAp';
  26.         die "cannot deal with this snapshot version"
  27.                 if $header->{version} != 1;
  28.         die "snapshot is invalid, refusing to operate on it"
  29.                 unless $header->{valid};
  30.         die "unexpected chunk size"
  31.                 if ($header->{chunk_size} & ($header->{chunk_size}-1)) != 0;
  32.         printf "# found snapshot header for chunk_size=%u sectors\n", $header->{chunk_size};
  33. }

  34. sub seek_to_exception_table($)
  35. {
  36.         my $n = $_[0];
  37.         my $cs = $header->{chunk_size} * 512;
  38.         my $epc = $cs / 16;
  39.         my $pos = ($n*($epc+1)+1)*$cs;
  40.         sysseek(IN, $pos, 0) == $pos
  41.                 or die "sysseek(,$pos,): $!";
  42. }

  43. sub process_one_exception
  44. {
  45.         my ($old,$new,$merge_count) =  <at> _;
  46.         # chunk numbers!
  47.         # old: logical chunk number
  48.         # new: chunk number in exception store
  49.         # merge count: how many chunks could be merged
  50.         # with these start sectors

  51.         # chunk number mapping
  52.         # printf "#c %20.0f\t%20.0f\t%u\n", $old, $new, $merge_count;

  53.         # for sectors you'd have to multiply with $header->{chunk_size};

  54.         # dd command line
  55.         # if you dare,
  56.         # you can do it in perl directly!
  57.         # or implement it in C using pread/pwrite.
  58.         printf "#d dd of=\$origin seek=%.0f if=\$cow iflag=direct skip=%.0f count=%u bs=%ub\n",
  59.                 $old, $new, $merge_count, $header->{chunk_size};
  60.        
  61. }

  62. sub list_exceptions()
  63. {
  64.         my $cs = 512*$header->{chunk_size};
  65.         my $enr = 0;
  66.         my $ecount = 0;
  67.         my $e;
  68.         my  <at> t;
  69. EXCEPTION_CHUNK:
  70.         for ($enr = 0; seek_to_exception_table($enr); $enr++) {
  71.                 my $c = sysread(IN, $buf, $cs, $offset);
  72.                 die "problem reading exception table, \$c: $c, \$!: $!"
  73.                          if ($c != $cs);
  74.                  <at> t = unpack "V*", substr($buf, $offset, $cs);
  75.                 for (my $i = 0; $i <  <at> t; $i += 4) {
  76.                         # if the "new" location is equal to zero,
  77.                         # that was the END marker.
  78.                         last EXCEPTION_CHUNK unless $t[$i+2] || $t[$i+3];
  79.                         $ecount++;

  80.                         # unfortunately 64bit integer is not available
  81.                         # in many perl. we compensate:
  82.                         my ($old,$new) = (
  83.                                 $t[$i+1] * 4294967296.0 + $t[$i],
  84.                                 $t[$i+3] * 4294967296.0 + $t[$i+2]);

  85.                         # maybe we can merge?
  86.                         if ($e and
  87.                                 $old == $e->[0] + $e->[2] and
  88.                                 $new == $e->[1] + $e->[2])
  89.                         {
  90.                                 $e->[2]++;
  91.                                 next;
  92.                         }
  93.                         process_one_exception( <at> $e) if $e;
  94.                         $e = [ $old, $new, 1]
  95.                 }
  96.                 process_one_exception( <at> $e);
  97.                 # would not work anyways, $new mapping jumps, but lets
  98.                 # _explicitly_ only merge within one exception table chunk
  99.                 undef $e;
  100.         }
  101.         # don't forget to report the last mapping
  102.         process_one_exception( <at> $e) if $e;
  103.         printf "# found %.0f exceptions (%.0f kB)\n",
  104.                 $ecount, $ecount*$header->{chunk_size}/2;
  105.         print "## use these dd commands AT YOUR OWN RISK\n" if $ecount;
  106. }

  107. read_header;
  108. list_exceptions;
复制代码

论坛徽章:
0
2 [报告]
发表于 2014-10-17 14:40 |只看该作者
perl ????难道真没有人知道吗

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
3 [报告]
发表于 2014-10-17 16:42 |只看该作者
注释说的很清楚了

论坛徽章:
78
双子座
日期:2013-10-15 08:50:09天秤座
日期:2013-10-16 18:02:08白羊座
日期:2013-10-18 13:35:33天蝎座
日期:2013-10-18 13:37:06狮子座
日期:2013-10-18 13:40:31双子座
日期:2013-10-22 13:58:42戌狗
日期:2013-10-22 18:50:04CU十二周年纪念徽章
日期:2013-10-24 15:41:34巨蟹座
日期:2013-10-24 17:14:56处女座
日期:2013-10-24 17:15:30双子座
日期:2013-10-25 13:49:39午马
日期:2013-10-28 15:02:15
4 [报告]
发表于 2014-10-17 16:43 |只看该作者
        # dd command line
        # if you dare,
        # you can do it in perl directly!
        # or implement it in C using pread/pwrite.

论坛徽章:
0
5 [报告]
发表于 2014-10-17 20:41 |只看该作者
但是只是格左化打印出来没有执行真实的打操作: ./dm.sh /dev/loop0 /dev/loop1 是这样的吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP