【问题标题】:How to call shell subroutine from perl script如何从 perl 脚本调用 shell 子程序
【发布时间】:2015-07-30 18:56:12
【问题描述】:

我有一个 shell 脚本,其中编写了两个子例程,它们接受参数,按摩该参数,然后提供新值作为输出。

这个脚本被许多其他的 shell 脚本使用。现在我有一个 Perl 脚本,我想用参数调用这些 shell 子例程。以下是我的代码:

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

Perl 脚本:

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

所以在这里我想将 shell 子程序的输出变量的值分配给 Perl 脚本的输出变量。但我发现只有当我在 shell 子例程中回显该输出变量时它才可用,如下所示。

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

我不想回显输出变量,因为它是敏感数据并且会暴露在其他 shell 脚本的日志中。

请指教。

【问题讨论】:

    标签: perl shell


    【解决方案1】:
    my $output = `source /path/my_shell-script.sh; extract_data arg1; echo \$output`;
    

    您的 shell 函数正在 shell 中设置一个变量。但是当 shell 退出时,该变量会丢失。您需要将它打印到标准输出,Perl 的反引号正在捕获它。

    【讨论】:

    • 它给了我以下错误,因为 perl 脚本无法识别 shell 脚本的输出变量。全局符号“$output”在 may.pl 第 35 行需要明确的包名称。
    • 抱歉,忘记了反斜杠。
    【解决方案2】:

    当你使用时,如果没有任何文件描述符(默认情况下这是 stdout、stderr 和 stdin),就不可能在两个进程之间进行交互 系统,或`` 甚至open2/open3 调用。

    但是如果问题只是你不想破坏你的shell脚本的代码,你可以用shell中的另一个函数包装它并从perl调用它。 你可以这样做:

    将代码添加到my_shell-script.sh

    print_output()
    {
      echo $output
    }
    

    还有你的 perl 脚本:

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

    但这太可怕了。不要使用全局变量。这可能是一个很好的峰值。但最好使用return

    【讨论】:

      【解决方案3】:

      当 my_shell-script.sh 被 Perl 调用而不是被另一个脚本调用时,您希望得到回显。脚本必须决定它是否被 Perl 调用。
      两种方法是:

      1. 使用参数/选项告诉脚本它必须输出结果
      2. 让 my_shell-script.sh 检查父进程,并在父进程为 perl 时回显。

      既然你直接调用一个函数,你可以采取另一种解决方案。确保原始函数名称在没有回显的情况下工作,因此不需要编辑其他脚本。

      #!/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 脚本:

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

      【讨论】: