Reputation: 3448
This has been frustrating me for hours now. I wrote a simple wrapper around a Perl one-liner to update the serials in some DNS zone files.
I feel compelled to add this:- Don't offer other ways to do this, OK? It's about why this won't work, not about how to achieve the result by other means.
Here is my simple script
#!/bin/bash
#loop through the supplied files updating the timestamp (serial)
SERIAL=`date +%Y%m%d%H%M`;
for name in $@
do
saCMD="'s/^(\W*)\d*.*;\W*serial/\${1}$SERIAL ; serial/g'"
#echo the command
echo "perl -pi -e "$saCMD" $name"
#execute the command
`perl -pi -e $saCMD $name`
done
I have tried a multitude of different ways and it fails silently or with the message
Can't find string terminator "'" anywhere before EOF at -e line 1..
If I execute the echoed command it works faultlessly
I am on a Debian 7 system
Can anyone point out me to why this is not executing as I would expect it to?
Some example data
$TTL 300
domain.org. IN SOA ns1.domain.com. admin.domain.org. (
2014090914 ; serial, todays date+todays
7200 ; refresh, seconds
7200 ; retry, seconds
2419200 ; expire, seconds
3600 ) ; minimum, seconds
The line of interest is 2014090914 ; serial, todays date+todays
Upvotes: 3
Views: 3317
Reputation: 72786
There is at least a quoting issue. You make the single quotes a part of the saCMD="'s...'"
. They will not be removed by the shell but passed to perl, as you can see in the echo
output.
In addition,
#execute the command
`perl -pi -e $saCMD $name`
has likely useless backticks. Or do you also want to run a command that's being output by the perl script? To debug shell scripts, place set -x
at the beginning.
This works here:
#!/bin/bash
SERIAL=$(date +%Y%m%d%H%M)
for name in "$@"; do
saCMD="s/^(\W*)\d*.*;\W*serial/\${1}$SERIAL ; serial/"
perl -pi -e "$saCMD" "$name"
done
and turns your example data into
$TTL 300
domain.org. IN SOA ns1.domain.com. admin.domain.org. (
201508201330 ; serial, todays date+todays
7200 ; refresh, seconds
7200 ; retry, seconds
2419200 ; expire, seconds
3600 ) ; minimum, seconds
Upvotes: 2
Reputation: 242443
Proper quoting should help. You haven't shown the input data, so I can't test:
saCMD="s/^(\W*)\d*.*;\W*serial/\${1}$SERIAL ; serial/g" # No inner quotes.
perl -pi -e "$saCMD" "$name"
Also, /g
seems pointless as the regex only matches at the beginning of the string (^
).
Upvotes: 0