1

I have this kind of data in JSON format

 {
    "stream 8": {
       "stream_name": "xyz",
       "field1": "xe-0/0/1",
       "field2": "at-0/0/0"
    },
   "stream 12": {
      "stream_name": "abc",
       "field1": "br-0/1/1",
       "field2": "at-1/0/1"
    }
}

I sent this JSON object to a Perl CGI script where I converted it to a hash of hashes.

Now I want to send this hash reference to another Perl script using a command-line argument. I don't know why it's not working.

Here is my CGI script

#!c:/perl/bin/perl.exe

use CGI;

use strict;
use warnings;

use JSON;
use JSON::PP;
use Data::Dumper;
use Storable;

# read the CGI params
my $q    = CGI->new;
my $json = $q->param("r");
print "Content-type:text/html\n\n";
my $href = decode_json($json);

my %arr = %{$href};

my %hash;
foreach my $key (keys %arr) {

    my %a = %{$arr{$key}};
    foreach my $value (keys %a) {

        $hash{$key}{'streamname'} = $a{'stream_name'};
        $hash{$key}{'f1'} =  $a{'field1'};
        $hash{$key}{'f2'} = $a{'field2'};

    }
} 

my @h = %hash;
#print ref(@h);
print Dumper(@h);
my $out;
$out = `perl te.pl @h hashval`;

Te.pl

use strict;
use warnings;

use Data::Dumper;
use Storable;

print("\nIn sample\n");

if ( $ARGV[-1] eq 'hashval' ) {
    #print("\nIts hash\n");
    delete($ARGV[-1]);
    my %h1 = @ARGV;
    print Dumper(%h1);
}

When I print %h1 I don't get the desired output.

Please let me know how to exactly fix this as I am new to Perl and CGI.

Borodin
  • 126,100
  • 9
  • 70
  • 144
Yash Awasthi
  • 31
  • 1
  • 6
  • @mkHun: I've asked you before not to make trivial changes to other people's posts. Correcting a small letter to a capital is fine if you have a major change to make as well, but it's far too trivial to be done on its own – Borodin Apr 28 '16 at 08:59
  • I have no idea what you are doing, but it *may* be worth looking at **redis** as a data-structure server... http://stackoverflow.com/a/18227177/2836621 Just a thought. – Mark Setchell Apr 28 '16 at 09:02
  • @MarkSetchell i just need to pass this hash to another perl script for further processing as a command line argument – Yash Awasthi Apr 28 '16 at 09:07
  • 3
    Why do you need to pass the data on the command line? It's probably easiest just to write the JSON data to a temporary file and have `te.pl` read the file and call `decode_json` on the contents, but it's unclear whether that's possible – Borodin Apr 28 '16 at 09:12
  • 7
    `%arr` and `@h` are two of the most confusing variable names I've ever seen :-) – Dave Cross Apr 28 '16 at 10:20

2 Answers2

2

You should send the data as JSON. IPC::Open3 might be a good choice:

$pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR,
                'perl te.pl');
print CHLD_IN $r;
close CHLD_IN;

You could still read the result from CHLD_OUT instead of using backticks.

Within te.pl:

{
    local $/ = undef;
    my $json = <STDIN>;
}

Use the { ... } block to limit the modification of $/ to that operation.

...but why do you need to call an external script? Why not loading it via require or moving the required functions to a module?

Community
  • 1
  • 1
Sebastian
  • 2,472
  • 1
  • 18
  • 31
1

Your hash is nested. By printing it, you just get the reftype and address, so you're calling this command:

perl te.pl key HASH(0x2886cd0)

Which fails as parentheses are special for the shell.

I'd rather send the JSON to the script, maybe via a file or pipe.

choroba
  • 231,213
  • 25
  • 204
  • 289