当 Perl 嵌入到 shell 脚本中时,如何查看父脚本中用实际行号报告的语法错误?

The*_*des 4 bash perl runtime-error syntax-error embedded-script

完全没有正当理由,我在一个 Bash 函数中嵌入了一个非常重要的 Perl 脚本,该函数在autoenv .env文件中被调用。

它看起来像这样:

perl='
    $inverse = "\e[7m";
    $invoff  = "\e[27m";
    $bold    = "\e[1m";
    ?
'

perl -e "$perl" "$inputfile"
Run Code Online (Sandbox Code Playgroud)

我明白独立的 Perl 脚本和PATH变量是一回事,我明白Term::ANSIColor是一回事。这不是关于那个。

我的问题是,如果嵌入的 Perl 代码中存在语法错误,我怎样才能让 Perl 报告父 shell 脚本中的实际行号?

例如,假设perl=分配发生在该文件的第 120 行,但实际 Perl 代码的第 65 行存在语法错误。我明白了:

syntax error at -e line 65, near "s/(#.*)$/$comment\1$endcomment/"
Execution of -e aborted due to compilation errors.
Run Code Online (Sandbox Code Playgroud)

…但我想看到这个(父脚本中的实际行号):

syntax error at -e line 185, near "s/(#.*)$/$comment\1$endcomment/"
Run Code Online (Sandbox Code Playgroud)

我尝试过的事情(没有用):

  • 分配给 __LINE__
    • 甚至不知道为什么我认为这会奏效;它不是一个变量,它是一个常数,你会得到一个错误说明相同
  • 分配给$.( $INPUT_LINE_NUMBERwith use English)
    • 我很确定这无论如何都行不通,因为这就像NR在 Awk 中一样,而这显然不是它的用途

ike*_*ami 9

perlsyn 中所述,您可以使用以下指令来设置行号和(可选)后续行的文件名:

#line 42 "file.pl"
Run Code Online (Sandbox Code Playgroud)

这意味着你可以使用

#!/bin/sh

perl="#line 4 \"$0\""'
warn("test");
'

perl -e "$perl"
Run Code Online (Sandbox Code Playgroud)

输出:

$ ./a.sh
test at ./a.sh line 4.
Run Code Online (Sandbox Code Playgroud)

在使用 时没有避免硬编码行号的干净方法sh,但这是可能的。

#!/bin/sh

script_start=$( perl -ne'if (/^perl=/) { print $.+1; last }' -- "$0" )
perl="#line $script_start \"$0\""'
warn("test");
'

perl -e "$perl"
Run Code Online (Sandbox Code Playgroud)

另一方面,bash提供当前行号。

#!/bin/sh

script_start=$( perl -ne'if (/^perl=/) { print $.+1; last }' -- "$0" )
perl="#line $script_start \"$0\""'
warn("test");
'

perl -e "$perl"
Run Code Online (Sandbox Code Playgroud)