Reputation: 1
The following shell script is working fine while I execute it from a Linux prompt, but when it's called by a Unix service (e.g. inetd, etc.) it doesn't recognize the $ACT_NUM
variable inside the Perl script.
export ACT_NUM=$1
perl -pi -e '$v=$ENV{ACT_NUM};s/TRIGGER_VALUE" value="\d*"/TRIGGER_VALUE" value="$v"/>//' soa_triggering.xml
The soa_triggering.xml
content file is
<ins:Parameter name="TRIGGER_VALUE" value="1"/>
Upvotes: 0
Views: 108
Reputation: 295639
Regular expressions are insufficiently expressive to parse XML. For instance, your same value could be written out over three lines with the parameter order reversed, as:
<ins:Parameter
value="1"
name="TRIGGER_VALUE"/>
...or with numerous other variances (unexpected whitespace, &c). Trying to cover the corner cases -- which also include distinguishing content in CDATA and comments from actual tags -- is potentially sanity-impacting.
If you're editing XML, use an actual XML parser. One good choice is XMLStarlet:
xmlstarlet ed -i \
-u '//*[@name="TRIGGER_VALUE"]/@value' \
-v "$ACT_NUM" \
soa_triggering.xml
If you know what the ins
namespace points to, you can do better:
# 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
Upvotes: 2
Reputation: 53498
I think your problem is more fundamental than expansion of $1
- I'm going to hazard a guess that the regex isn't matching - because:
$v=$ENV{ACT_NUM};s/TRIGGER_VALUE" value="\d*"/TRIGGER_VALUE" value="$v"/>//
Is actually broken syntax - you're using /
as your regex separator, but you're also trying to include it in your pattern.
So if you actually run this code you get:
Useless use of numeric gt (>) in void context
So perhaps you need to consider escaping some of your meta characters:
This works:
#!/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"/>
But really - messing around with XML
using regular expressions is an inherently bad idea.
You also might want to double check that that environment actually is being propagated. If you print $v
(or $ENV{ACT_NAME}
) does it actually work?
So how about instead:
#!/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;
Upvotes: 6