Hi Monks,
There's nothing fun about having to come in front of people and announce abject failure. Everything I'm to post here will be garbage that didn't work. I wasn't intending to do something grandiose, simply trying to use Path::Tiny and its methods to copy files and directories to a place where I will archive them. But how does a person produce self-contained code and data for others to see, when the message always seems to be "no such file or directory"? How can the diagnostic luminaries at the monastery know what does or does not exist on my machine when I can't seem to be sure which end of my copy method calls are not working?
At first, I was trying to work on it using the tempdir ideas at dagolden 2013 path-tiny feature. After all, I didn't need to have the copied files after a compressed archive exists. I made a manifest of the files I wanted copied from the "grandfather directory," using ls >1.manifest, and then winnowed the list down to files and directories I want. (I have no appropriate code for the directories yet, but a file is the first item on the list, and I have yet to get it copied once.)
The caller uses a library wherein it finds utils2.pm, where I have 3 archive functions. They all result in errors. I uncover the hashmarks to adjust the callee:
#!/usr/bin/perl -w use 5.011; use lib "template_stuff"; use utils2; #my $return1 = archive1(); #say "return is $return1"; #my $return2 = archive2(); #say "return is $return2"; my $return3 = archive3(); say "return is $return3"; __END__
This is the output from the call to archive1():
$ ./3.archive.pl path1 is /home/bob/1.scripts/pages/1.qy parent2 is /home/bob/1.scripts/pages files are 2.create.bash 11.clone.pl 1.initialize.pl 1.manifest 1.med 1.meditation 1.pop 1.qy 1.rings 2.med 5.create.sh 5.unicode temp dir is /tmp/backup_2elt_b read me is /tmp/backup_2elt_b/grandfather/README.txt copy failed for /home/bob/1.scripts/pages/2.create.bash to /tmp/backup_2elt_b/grandfather: No such file or directory at templ +ate_stuff/utils2.pm line 32. cannot remove path when cwd is /tmp/backup_2elt_b/grandfather for /tmp +/backup_2elt_b: at /usr/share/perl/5.26/File/Temp.pm line 1583. $
copy failed for /home/bob/1.scripts/pages/2.create.bash to /tmp/backup_2elt_b/grandfather: No such file or directory at template_stuff/utils2.pm line 32.<
line 32 is the one with the copy command:
sub archive1 { use warnings; use 5.011; use Path::Tiny; my $path1 = Path::Tiny->cwd; say "path1 is $path1"; my $parent1 = $path1->parent(); say "parent2 is $parent1"; my $file1 = "1.manifest"; my $from = path( $parent1, $file1 ); my @files = $from->lines_utf8; say "files are @files"; my $tempdir = Path::Tiny->tempdir('backup_XXXXXX'); say "temp dir is $tempdir"; my $readme = $tempdir->child( 'grandfather', 'README.txt' )->touchpa +th; say "read me is $readme"; my $grand_dir = $readme->parent; chdir $grand_dir; foreach my $file (@files) { #syntax is from -> to my $return = path( $parent1, $file )->copy( $grand_dir, $file ); if ( $file =~ m/\.(pl|sh)$/ ) { $return->chmod(0755); } say "return is $return"; } system("cd $grand_dir"); system("ls -l"); my $b = "dummy"; return $b; }
The LHS of the copy command looks solid to me, as it could find the manifest in that directory and list its contents. So the RHS must* be the problem, and I wondered if the /tmp directory had disappeared before the file copy could happen. No sign of the directory created with the touchpath command existed after the program was finished with execution.
*true only if my logic is solid, which it manifestly isn'tSo I try a version that does not rely on a tempdir and we come to archive2(). I had only recently created space on my machine for this html template to hold its .ini files, so I thought I could use it for archiving at least until I get myself out of this jam. This place exists already:
$ pwd /home/bob/Documents/html_template_data $ ls 3.values.ini example3.ini $
Abridged output and then source:
$ ./3.archive.pl path1 is /home/bob/1.scripts/pages/1.qy parent1 is /home/bob/1.scripts/pages files are 2.create.bash 11.clone.pl 1.initialize.pl 1.manifest 1.med 1.meditation 1.pop 1.qy 1.rings 2.med 5.create.sh 5.unicode grand dir is /home/bob/Documents/html_template_data $VAR1 = 1; -----from /home/bob/1.scripts/pages ... 2.create.bash clone1.pl fork UserAgentWithS +tats.pm ... path 3 is /home/bob/1.scripts/pages/2.create.bash $VAR1 = 1; -----to /home/bob/Documents/html_template_data 3.values.ini example3.ini path 4 is /home/bob/Documents/html_template_data/2.create.bash copy failed for /home/bob/1.scripts/pages/2.create.bash to /home/bob/Documents/html_template_data/2.create.bash : No such file or directory at template_stuff/utils2.pm line 80. $
I make the paths as explicit as I know how to in the ultimate version, whose output and source are within readmore tags. I include the entire .pm here.
$ ./3.archive.pl path1 is /home/bob/1.scripts/pages/1.qy parent1 is /home/bob/1.scripts/pages files are 2.create.bash 11.clone.pl 1.initialize.pl 1.manifest 1.med 1.meditation 1.pop 1.qy 1.rings 2.med 5.create.sh 5.unicode grand dir is /home/bob/Documents/html_template_data path 3 is /home/bob/1.scripts/pages/2.create.bash path 4 is /home/bob/Documents/html_template_data/2.create.bash copy failed for /home/bob/1.scripts/pages/2.create.bash to /home/bob/Documents/html_template_data/2.create.bash : No such file or directory at template_stuff/utils2.pm line 129. $ $ cat utils2.pm package utils2; require Exporter; use utils1; our @ISA = qw(Exporter); our @EXPORT = qw( archive1 archive2 archive3); sub archive1 { use warnings; use 5.011; use Path::Tiny; my $path1 = Path::Tiny->cwd; say "path1 is $path1"; my $parent1 = $path1->parent(); say "parent2 is $parent1"; my $file1 = "1.manifest"; my $from = path( $parent1, $file1 ); my @files = $from->lines_utf8; say "files are @files"; my $tempdir = Path::Tiny->tempdir('backup_XXXXXX'); say "temp dir is $tempdir"; my $readme = $tempdir->child( 'grandfather', 'README.txt' )->touchpa +th; say "read me is $readme"; my $grand_dir = $readme->parent; chdir $grand_dir; foreach my $file (@files) { #syntax is from -> to my $return = path( $parent1, $file )->copy( $grand_dir, $file ); if ( $file =~ m/\.(pl|sh)$/ ) { $return->chmod(0755); } say "return is $return"; } system("cd $grand_dir"); system("ls -l"); my $b = "dummy"; return $b; } sub archive2 { use warnings; use 5.011; use Path::Tiny; use Data::Dumper; my $path1 = Path::Tiny->cwd; say "path1 is $path1"; my $parent1 = $path1->parent(); say "parent1 is $parent1"; my $file1 = "1.manifest"; my $from = path( $parent1, $file1 ); my @files = $from->lines_utf8; say "files are @files"; my $grand_dir = "/home/bob/Documents/html_template_data"; say "grand dir is $grand_dir"; foreach my $file (@files) { #syntax is from -> to my $path3 = path($parent1, $file); my $return6 = chdir $parent1 or warn "why is this not here?"; say Dumper $return6; say "-----from"; system("pwd"); system("ls"); say "path 3 is $path3"; my $return5 = chdir $grand_dir or warn "why is this not here?"; say Dumper $return5; say "-----to"; system("pwd"); system("ls"); my $path4 = path($grand_dir, $file ); say "path 4 is $path4"; my $return = path( $path3 )->copy( $path4); say Dumper $return; if ( $file =~ m/\.(pl|sh)$/ ) { $return->chmod(0755); } say "return is $return"; } system("cd $grand_dir"); system("ls -l"); my $b = "dummy"; return $b; } sub archive3 { use warnings; use 5.011; use Path::Tiny; use Data::Dumper; my $path1 = Path::Tiny->cwd; say "path1 is $path1"; my $parent1 = $path1->parent(); say "parent1 is $parent1"; my $file1 = "1.manifest"; my $from = path( $parent1, $file1 ); my @files = $from->lines_utf8; say "files are @files"; my $grand_dir = "/home/bob/Documents/html_template_data"; say "grand dir is $grand_dir"; #system ("cd $parent1\/"); # system ("pwd"); foreach my $file (@files) { #syntax is from -> to my $path3 = path($parent1, $file); say "path 3 is $path3"; #my $path5 = path($path3)->assert( sub { $path3->exists } ); #say "path 5 is $path5"; my $path4 = path($grand_dir, $file ); say "path 4 is $path4"; my $return = path( $path3 )->copy( $path4); say Dumper $return; if ( $file =~ m/\.(pl|sh)$/ ) { $return->chmod(0755); } } my $b = "dummy"; return $b; } 1; $
My first Big question is how do I write these copy commands correctly? The only thing that all of these crummy functions have in common is me.
Also, when I sent the returned value to Data::Dumper, I got "1" instead of a hash. How do I pick apart the error message properly?
EXCEPTION HANDLING Simple usage errors will generally croak. Failures of underlying Perl +functions will be thrown as exceptions in the class Path::Tiny::Error +. A Path::Tiny::Error object will be a hash reference with the following + fields: op — a description of the operation, usually function call and any + extra info file — the file or directory relating to the error err — hold $! at the time the error was thrown msg — a string combining the above data and a Carp-like short stac +k trace Exception objects will stringify as the msg field.
Finally, is this anywhere near how the assert feature of Path::Tiny is to be used?
my $path3 = path($parent1, $file); say "path 3 is $path3"; #my $path5 = path($path3)->assert( sub { $path3->exists } ); #say "path 5 is $path5";
Why is it so much harder to copy files in perl than bash? Thank you for your comments.
In reply to creating valid paths for Path::Tiny by Aldebaran
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |