当我从Linux提示符执行它时,下面的shell脚本工作正常,但是当它被Unix服务(例如inetd等)调用时,它无法识别Perl脚本中的$ACT_NUM
变量。
export ACT_NUM=$1
perl -pi -e '$v=$ENV{ACT_NUM};s/TRIGGER_VALUE" value="d*"/TRIGGER_VALUE" value="$v"/>//' soa_triggering.xml
soa_triggering.xml
内容文件是
<ins:Parameter name="TRIGGER_VALUE" value="1"/>
我认为你的问题比$1
的扩展更根本 - 我会冒险猜测正则表达式不匹配 - 因为:
$v=$ENV{ACT_NUM};s/TRIGGER_VALUE" value="d*"/TRIGGER_VALUE" value="$v"/>//
实际上是损坏的语法 - 您正在使用/
作为正则表达式分隔符,但您也尝试将其包含在您的模式中。
因此,如果您实际运行此代码,您将获得:
Useless use of numeric gt (>) in void context
所以也许你需要考虑转义你的一些元字符:
这有效:
#!/usr/bin/env perl
use strict;
use warnings;
$ENV{ACT_NUM} = 1;
while ( <DATA> ) {
my $v=$ENV{ACT_NUM};
s/TRIGGER_VALUE" value="d*"/TRIGGER_VALUE" value="$v"/;
print;
}
__DATA__
<ins:Parameter name="TRIGGER_VALUE" value="1"/>
但实际上 - 使用正则表达式弄乱XML
本质上是一个坏主意。
您可能还需要仔细检查该环境是否确实正在传播。如果你print $v
(或$ENV{ACT_NAME}
)它真的有效吗?
那么呢:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
twig_handlers => {
'ins:Parameter[@name="TRIGGER_VALUE"]' =>
sub { $_->set_att( 'value', $ENV{ACT_NUM} ) }
}
);
$twig->parse(
do { local $/; <> }
)->print;
正则表达式的表达能力不足以解析 XML。例如,您的相同值可以写出三行,参数顺序颠倒,如下所示:
<ins:Parameter
value="1"
name="TRIGGER_VALUE"/>
。或具有许多其他差异(意外的空格等)。试图涵盖极端情况(还包括区分 CDATA 中的内容和注释与实际标记)可能会影响健全性。
如果要编辑 XML,请使用实际的 XML 分析器。一个不错的选择是XMLStarlet:
xmlstarlet ed -i
-u '//*[@name="TRIGGER_VALUE"]/@value'
-v "$ACT_NUM"
soa_triggering.xml
如果您知道ins
命名空间指向什么,则可以做得更好:
# Replace http://example.com/ins-namespace with actual value
# from xmlns:ins="..." earlier in your document
xmlstarlet ed -i -N "ins=http://example.com/ins-namespace"
-u '//ins:Parameter[@name="TRIGGER_VALUE"]/@value'
-v "$ACT_NUM"
soa_triggering.xml