CuriousOne
CuriousOne

Reputation: 35

How to call shell subroutine from perl script

I have a shell script where there are two subroutines written which take argument, massage that argument & then provide new value as an output.

This script is used by many other shell scripts. Now I have a Perl script where I want to call these shell subroutines with arguments. Below is my code:

#! /bin/sh
extract_data()
{
  arg1 = $1
  // massage data code
  output=massaged data 
  return 0
}

Perl script:

my $output = `source /path/my_shell-script.sh; extract_data arg1`;

So here I want to assign value of output variable from shell subroutine to output variable of Perl script. But what I have found is it is available only if I echo that output variable in shell subroutine like below.

#! /bin/sh
extract_data()
{
arg1 = $1
// massage data code
output=massaged data
echo $output 
}

I do not want to echo output variable as it is sensitive data & will be exposed in the logs of other shell scripts.

Please advise.

Upvotes: 0

Views: 379

Answers (3)

cjm
cjm

Reputation: 62099

my $output = `source /path/my_shell-script.sh; extract_data arg1; echo \$output`;

Your shell function is setting a variable in the shell. But that variable is lost when the shell exits. You need to print it to stdout, which Perl's backticks are capturing.

Upvotes: 1

Igor Karbachinsky
Igor Karbachinsky

Reputation: 385

It's impossible to make an interaction between two processes without any file descriptor (by default this is stdout, stderr and stdin) when you use system, or `` or even open2/open3 calls.

But if the problem is only that you don't want to break the code of your shell script, you can wrap it with another function in shell and call it from perl. You can do something like this:

Add code to my_shell-script.sh:

print_output()
{
  echo $output
}

And your perl script:

my $output = `source /path/my_shell-script.sh; extract_data arg1; print_output`;

But this is terrible. Don't use global variables. This could be a good spike. But it would be better to use return.

Upvotes: 2

Walter A
Walter A

Reputation: 20002

You want to have an echo when my_shell-script.sh is called by Perl and not when it is called by another script. The script must decide if it is called by Perl.
Two methods are:

  1. Use a parameter/option to tell the script it must output the result
  2. Let my_shell-script.sh check the parent process and echo when the parent is perl.

Since you call a function directly, you can take another solution. Make sure the original function name works without an echo, so other scripts don't need to be edited.

#!/bin/sh
extract_data_process()
   arg1=$1
   // massage data code
   output=massaged data
   echo $output 
}

extract_data()
{
   extract_data_process $1 >/dev/null 2>&1
   return 0
}

extract_data_verbose()
{
   output=$(extract_data_process $1 2>&1)
   echo "${output}"
   return 0
}

Perl script:

my $output = `source /path/my_shell-script.sh; extract_data_verbose arg1`;

Upvotes: 1

Related Questions