Perl string replace with backreferenced values and shell variables

Let’s say ‘pm.max_children = 8’ on the file ‘/usr/local/etc/php-fpm.d/www.conf’
The result of the following is supposed to be 40 but $1 is just ignored.

aaa=5
perl -i.bak -e "s/pm.max_children\s*=\s*\K([0-9]+)/($1 * $aaa)/ge" /usr/local/etc/php-fpm.d/www.conf

But the strange thing is the following is working, in case $aaa is not a variable.

perl -i.bak -e "s/pm.max_children\s*=\s*\K([0-9]+)/($1 * 3)/ge" /usr/local/etc/php-fpm.d/www.conf

>Solution :

The meaning of $1 is different in the shell and in Perl.

In the shell, it means the first positional argument. As double quotes expand variables, $1 in double quotes also means the first positional argument.

In Perl, $1 means the first capture group matched by a regular expression.

But, if you use $1 in double quotes on the shell level, Perl never sees it: the shell expands $1 as the first positional argument and sends the expanded string to Perl.

You can use the %ENV hash in Perl to refer to environment variables:

aaa=5 perl -i.bak -pe 's/pm.max_children\s*=\s*\K([0-9]+)/($1 * $ENV{aaa})/ge' /usr/local/etc/php-fpm.d/www.conf

Leave a Reply