http://www.perlmonks.org?node_id=11104765

coolsaurabh has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am in process of uploading file to S3 storage via Perl script. Below script is used to upload the file.However when i am trying to print the bucket and filename which is earlier uploaded,the script is throwing some error. Pls advice.
Script to upload file on S3 #!/opt/perl/bin/perl use Amazon::S3; my $file_name = "filename.txt"; my $bucketName = "forest-upload"; my $s3 = Amazon::S3->new({ aws_access_key_id => "XXX", aws_secret_access_key => "XXX", retry => 1 }); my $bucket = $s3->bucket($bucketName); $bucket->add_key_filename( $file_name, $file_name, { content_type => "text/plain", } ); Script for printing the bucket and filename #!/opt/perl/bin/perl use Amazon::S3; my $access_key = 'XXX'; my $secret_key = 'XXX'; my $conn = Amazon::S3->new({ aws_access_key_id => $access_key, aws_secret_access_key => $secret_key, secure => 1, retry => 1, }); my @buckets = @{$conn->buckets->{buckets} || []}; foreach my $bucket (@buckets) { print $bucket->bucket . "\t" . $bucket->creation_date . "\n"; }
The error which above script is throwing is "Can't use an undefined value as a HASH reference at Amazon_bucket.pl line 16."

Replies are listed 'Best First'.
Re: Need to print bucket and filename which is uploaded on S3 storage
by Corion (Pope) on Aug 21, 2019 at 07:28 UTC

    The ->buckets method returns undef on error. So you have an error.

    Look at the ->err and ->errstr methods for the error message.

Re: Need to print bucket and filename which is uploaded on S3 storage
by Athanasius (Bishop) on Aug 21, 2019 at 07:41 UTC

    Hello coolsaurabh,

    I’m assuming that “line 16” is this one:

    my @buckets = @{$conn->buckets->{buckets} || []};

    Now, the documentation for the Amazon::S3::buckets method says it “Returns undef on error, else HASHREF of results.” So you need to test for an undef return value before attempting to dereference the hash reference. For example:

    my $result = $conn->buckets(); my @buckets; @buckets = @{ $result->{buckets} } if defined $result;

    This way, if the call to buckets() returns undef, no dereference is attempted and @buckets remains unchanged as an empty list.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      The output of this script is blank.
      #!/opt/perl/bin/perl use Amazon::S3; my $file_name = "filename.txt"; my $bucketName = "forest-upload"; my $s3 = Amazon::S3->new({ aws_access_key_id => "XX", aws_secret_access_key => "XX", retry => 1 }); my $bucket = $s3->bucket($bucketName); $bucket->add_key_filename( $file_name, $file_name, { content_type => "text/plain", } ); my $result = $s3->buckets(); my @buckets; @buckets = @{ $result->{buckets} } if defined $result;

        That means there was an error returned by Amazon.

        Have you checked the errors in $s3->err and $s3->errstr?

        Also, maybe you have not created any buckets yet?

        the script has no calls to "print" or "say", so why would you expect non-blank output?
      Thanks for the response. It means the script which I ran to upload the file on S3 didn't worked else it should have printed the bucket name isn't it????

        You never check the result of ->add_key_filename. Maybe that is a good point to start?

        Also, have you verified that your bucket "forest-upload" exists?

        the new script doesn't have this line, so it won't print anything:
        print $bucket->bucket . "\t" . $bucket->creation_date . "\n";
        unless i just don't understand the code at all...
Re: Need to print bucket and filename which is uploaded on S3 storage
by 1nickt (Abbot) on Aug 21, 2019 at 14:30 UTC

    Hi, why are you using a module that has not been updated since 2009 to access a commercial cloud service?

    How I store stuffs in S3 these days:

    my $s3 = Net::Amazon::S3->new({ aws_access_key_id => $conf->{access_key}, aws_secret_access_key => $conf->{secret_key}, }); my $bucket = $s3->bucket( $conf->{bucket} ); my $key = $conf->{path}{ $op_env } . '/some_name'; $bucket->add_key( $key, $data ) or $die($s3->err . ": " . $s3->errstr) +;

    Hope this helps!


    The way forward always starts with a minimal test.