【问题标题】:Run Perl Script From Unix Shell Script从 Unix Shell 脚本运行 Perl 脚本
【发布时间】:2014-09-29 19:18:51
【问题描述】:

您好,我有一个 Unix Shell 脚本调用 Food.sh ;我有一个 Perl 脚本调用 Track.pl。有没有办法可以将 Track.pl 的代码放入 Food.sh 代码中并且仍然可以使用? Track.pl 需要一个参数来标记文件夹的名称。

基本上它会这样运行。

Unix Shell Script codes RUN

step into 

Perl Script codes RUN
Put in name of folder for Perl script
Rest of script runs

exit out.

【问题讨论】:

    标签: perl shell unix


    【解决方案1】:

    你有几个选择。

    1. 您可以使用 -e/-E 将代码传递给 Perl。

       ...
       perl -e'
      
          print "Hello, World!\n";
      
       '
       ...
      

      缺点:逃避可能会很痛苦。[1]

    2. 您可以通过 STDIN 传递代码。

       ...
       perl <<'END_OF_PERL'
      
          print "Hello, World!\n";
      
       END_OF_PERL
       ...
      

      缺点:脚本不能使用 STDIN。

    3. 您可以创建一个虚拟文件。

       ...
       perl <(
       cat <<'END_OF_PERL'
      
          print "Hello, World!\n";
      
       END_OF_PERL
       )
       ...
      

      缺点:啰嗦。

    4. 您可以利用perl-x 选项。

       ...
       perl -x -- "$0"
       ...
       exit
      
       #!perl
       print "Hello, World!\n";
      

      Con:只能有一个 sn-p。

      $0 是正在执行的 shell 脚本的路径。它作为要运行的程序传递给perl-x 告诉 Perl 从 #!perl 行而不是第一行开始执行。

    参考:perlrun


    1. 程序中'的实例需要使用'\''进行转义。

      您也可以重写程序以避免使用'。例如,您可以使用双引号字符串文字而不是单引号字符串文字。或者替换单引号字符串文字的分隔符(例如 q{...} 而不是 '...')。至于双引号和正则表达式中的单引号,这些可以替换为\x27,您可能会发现它比'\'' 更好。

    【讨论】:

    • 来自链接文档:-x 告诉 Perl 该程序嵌入在更大的不相关文本块中,例如在邮件消息中。前导垃圾将被丢弃,直到第一行以#开头!并包含字符串“perl”。将应用该行上任何有意义的开关。
    • 当我读完perlrun 准备回答时,我发现有两个非常好的答案正在等待。你们太快了……
    • 谢谢,我认为在此处包含该信息以保持您的答案独立可能会很有用。所以exit 属于shell 脚本,"$0" 是传递给perl 脚本的参数。
    • @TomFenech $0 是 shell 脚本自己的文件名。它作为要运行的程序传递给 perl 本身。 -x 限制运行以“#!”开头的行之后的内容。并包含“perl”
    【解决方案2】:

    (我假设您的目标只是将所有代码放在一个文件中,这样您就不需要安装多个文件)

    当然,有办法做到这一点,但它很麻烦。您可能需要考虑将 shell 脚本完全转换为 Perl(或将 Perl 脚本完全转换为 shell)。

    所以... 一种方法可能是:

    #!/bin/sh
    
    echo "shell"
    
    perl -E '
    say "perl with arg=$ARGV[0]"
    ' fred
    
    echo "shell again"
    

    当然,您必须小心在程序的 Perl 部分中使用引号。

    您也可以为 Perl 部分使用 heredoc 以避免引用问题,但我不确定。

    【讨论】:

    • 我认为应该是-e,而不是-E
    • @Tom Fenech, -E-e 加上隐含的 use feature ":".substr($^V,1);
    • 所以它为运行单行的 Perl 版本启用了feature bundle
    • @TomFenech 是的。它是在 5.10.0 中引入的,因此您不会在旧版本的 perl 中找到它。