首页 > 解决方案 > 当 Perl 嵌入 shell 脚本时,如何查看在父脚本中使用实际行号报告的语法错误?

问题描述

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

它看起来像这样:

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

perl -e "$perl" "$inputfile"

我知道独立的 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.

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

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

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

标签: bashperlsyntax-errorruntime-errorembedded-script

解决方案


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

#line 42 "file.pl"

这意味着您可以使用

#!/bin/sh

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

perl -e "$perl"

输出:

$ ./a.sh
test at ./a.sh line 4.

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

#!/bin/sh

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

perl -e "$perl"

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

#!/bin/bash

script_start=$(( LINENO + 2 ))
perl="#line $script_start \"$0\""'
warn("test");
'

perl -e "$perl"

推荐阅读