Recently I had to extract a partial string from a space-seperated list of names in a loop within a script. There have to be two versions of that script, one for Windows and one for Linux shell. To loop through one such list is quite easy, in Windows:

@echo off
SETLOCAL
set WEBSITES=Test1 Test2 Test3

FOR /D %%A IN (%WEBSITES%) DO (
 echo WebsiteName=%%A
)
GOTO :EOF

ENDLOCAL

and in Linux shell:

WEBSITES="Test1 Test2 Test3"

for WEBSITE_ALIAS in $WEBSITES ; do
 echo "Website= $WEBSITE_ALIAS ..."
done

But now came a second list of string into play containing the domain names of the website aliases:

WEBSITES="Test1 Test2 Test3"
DOMAINNAMES="www.test1.lan www.test2.lan www.test3.lan"

In a conventional programming language I would just use a for-loop with an index variable and utilize that variable to access both arrays within one loop. But in that batch/shell scripting this turned out to be quite tricky. My solution here was a small inline PERL script. For Windows:

set WEBSITE_UNIT=Unit4
set WEBSITES=Test1 Test2 Test3
set DOMAINNAMES=www.test1.lan www.test2.lan www.test3.lan
perl -e "use strict; die(\"argv mismatch!\") if !@ARGV or scalar(@ARGV) < 2; my @Websites = split(/[\s,;\|]/, $ARGV[0]); my @Domains = split(/[\s,;\|]/, $ARGV[1]); die(\"number of aliases differs from domain names!\") if scalar(@Websites) != scalar(@Domains); for(my $i=0; $i<scalar(@Websites); $i++) { system('perl dosomething.pl -user /Root/'.$ENV{'WEBSITE_UNIT'}.'/admin -passwd admin -servername '.$ENV{'SERVER_NAME'}.' -alias '.$Website[$i].''); system('perl doanotherthing.pl -user /Root/'.$ENV{'WEBSITE_UNIT'}.'/admin -passwd admin -alias '.$Website[$i].' DomainName=\"'.$Domains[$i].'\"'); }" "%WEBSITES%" "%DOMAINNAMES%"

And for Linux:

WEBSITE_UNIT=Unit4
WEBSITES="Test1 Test2 Test3"
DOMAINNAMES="www.test1.lan www.test2.lan www.test3.lan"
perl -e 'use strict; die("argv mismatch!") if !@ARGV or scalar(@ARGV) < 2; my @Websites = split(/[\s,;\|]/, $ARGV[0]); my @Domains = split(/[\s,;\|]/, $ARGV[1]); die("number of aliases differs from domain names!") if scalar(@Websites) != scalar(@Domains); for(my $i=0; $i<scalar(@Websites); $i++) { system("perl dosomething.pl -user /Root/'${WEBSITE_UNIT}'/admin -passwd admin -servername ".$ENV{"SERVER_NAME"}." -alias ".$Website[$i].""); system("perl doanotherthing.pl -user /Root/'${WEBSITE_UNIT}'/admin -passwd admin -alias ".$Website[$i]." DomainName=\"".$Domains[$i]."\"");  }' "$WEBSITES" "$DOMAINNAMES"

Notice the different handling of the ticks and quotes and the different access to external parameters. In Windows there’s no difference in PERL’s $ENV hash whether accessing real environment variables or local variables set by the batch script. Not so under Linux: I can only access my system-wide exported environment variable SERVER_NAME using $ENV but not my local script’s WEBSITE_UNIT variable. When using the exec -e with perl for Windows I had to use quotes to wrap the execution PERL-code but for linux shell, I needed single -ticks which can NOT be used inside the PERL code – not event when escapting them like \’. The single ticks are “reserved” by the shell script for being able to insert shell variables anywhere.